修复保存选择集使用旧方法引起的保存整个分层的bug
This commit is contained in:
parent
2cb9475847
commit
034ca80db2
@ -1840,35 +1840,24 @@ namespace NavisworksTransport.UI.WPF.ViewModels
|
||||
LogManager.Info($"[LayerManagementViewModel] 开始保存选中项目到: {saveFilePath}");
|
||||
LogManager.Info($"[LayerManagementViewModel] 保存 {originalSelection.Count} 个选中节点及其所有子项");
|
||||
|
||||
// 4. 使用基于多选节点的保存逻辑
|
||||
// 4. 使用借鉴自 ModelSplitterManager.ExportLayerToNwd 的精确隔离逻辑
|
||||
bool exportResult = false;
|
||||
string errorMessage = "";
|
||||
|
||||
try
|
||||
{
|
||||
// 收集所有需要显示的节点(选中的节点和它们的祖先节点)
|
||||
var nodesToKeepVisible = new HashSet<ModelItem>();
|
||||
|
||||
// 对于每个选中的节点,收集它和它的所有祖先节点
|
||||
// 收集要导出的项目(包含子节点)
|
||||
var itemsToExport = new List<ModelItem>();
|
||||
|
||||
foreach (var selectedItem in originalSelection)
|
||||
{
|
||||
// 添加选中节点本身
|
||||
nodesToKeepVisible.Add(selectedItem);
|
||||
LogManager.Info($"[LayerManagementViewModel] 添加选中节点到可见列表: {selectedItem.DisplayName}");
|
||||
|
||||
// 添加所有祖先节点,确保选中节点的路径可见
|
||||
var current = selectedItem.Parent;
|
||||
while (current != null)
|
||||
{
|
||||
nodesToKeepVisible.Add(current);
|
||||
LogManager.Info($"[LayerManagementViewModel] 添加祖先节点到可见列表: {current.DisplayName}");
|
||||
current = current.Parent;
|
||||
}
|
||||
itemsToExport.Add(selectedItem);
|
||||
LogManager.Info($"[LayerManagementViewModel] 添加选中节点到导出列表: {selectedItem.DisplayName}");
|
||||
|
||||
// 添加所有子节点(如果用户开启了包含子节点选项)
|
||||
if (IncludeChildNodes)
|
||||
{
|
||||
// 使用正确的Navisworks API遍历子节点
|
||||
try
|
||||
{
|
||||
// 使用DescendantsAndSelf来获取所有后代节点
|
||||
@ -1877,7 +1866,7 @@ namespace NavisworksTransport.UI.WPF.ViewModels
|
||||
|
||||
foreach (ModelItem child in childItems)
|
||||
{
|
||||
nodesToKeepVisible.Add(child);
|
||||
itemsToExport.Add(child);
|
||||
childCount++;
|
||||
}
|
||||
|
||||
@ -1890,141 +1879,81 @@ namespace NavisworksTransport.UI.WPF.ViewModels
|
||||
}
|
||||
}
|
||||
|
||||
LogManager.Info($"[LayerManagementViewModel] 总共需要保持可见的节点数量: {nodesToKeepVisible.Count}");
|
||||
LogManager.Info($"[LayerManagementViewModel] 总共需要导出的节点数量: {itemsToExport.Count}");
|
||||
|
||||
// 使用正确的Navisworks API收集顶级节点
|
||||
// 根据示例,这是正确的方式来获取所有顶级模型项
|
||||
var allTopLevelItems = new List<ModelItem>();
|
||||
|
||||
// 使用RootItemDescendantsAndSelf,但只取第一级子项
|
||||
foreach (Model model in document.Models)
|
||||
{
|
||||
foreach (ModelItem topLevelItem in model.RootItem.Children)
|
||||
{
|
||||
allTopLevelItems.Add(topLevelItem);
|
||||
}
|
||||
}
|
||||
|
||||
LogManager.Info($"[LayerManagementViewModel] 收集到 {allTopLevelItems.Count} 个顶级节点");
|
||||
|
||||
// 更智能的隐藏策略:
|
||||
// 1. 如果选中节点包含某个顶级节点或其子节点,则该顶级节点保持可见
|
||||
// 2. 否则隐藏整个顶级节点分支
|
||||
var itemsToHide = new ModelItemCollection();
|
||||
int hiddenCount = 0;
|
||||
|
||||
foreach (ModelItem topLevelItem in allTopLevelItems)
|
||||
{
|
||||
bool shouldKeepTopLevel = false;
|
||||
|
||||
// 检查这个顶级节点或其任何子节点是否需要保持可见
|
||||
if (nodesToKeepVisible.Contains(topLevelItem))
|
||||
{
|
||||
shouldKeepTopLevel = true;
|
||||
LogManager.Info($"[LayerManagementViewModel] 顶级节点 {topLevelItem.DisplayName} 本身被选中,保持可见");
|
||||
}
|
||||
else
|
||||
{
|
||||
// 检查是否有任何选中节点是这个顶级节点的后代
|
||||
foreach (var selectedItem in originalSelection)
|
||||
{
|
||||
var current = selectedItem;
|
||||
while (current != null)
|
||||
{
|
||||
if (current == topLevelItem)
|
||||
{
|
||||
shouldKeepTopLevel = true;
|
||||
LogManager.Info($"[LayerManagementViewModel] 顶级节点 {topLevelItem.DisplayName} 包含选中节点,保持可见");
|
||||
break;
|
||||
}
|
||||
current = current.Parent;
|
||||
}
|
||||
if (shouldKeepTopLevel) break;
|
||||
}
|
||||
}
|
||||
|
||||
// 如果这个顶级节点不需要保持可见,则隐藏它
|
||||
if (!shouldKeepTopLevel)
|
||||
{
|
||||
try
|
||||
{
|
||||
itemsToHide.Add(topLevelItem);
|
||||
hiddenCount++;
|
||||
LogManager.Info($"[LayerManagementViewModel] 隐藏顶级节点: {topLevelItem.DisplayName}");
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
LogManager.Warning($"[LayerManagementViewModel] 添加隐藏项目失败: {topLevelItem.DisplayName} - {ex.Message}");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 执行隐藏操作
|
||||
if (itemsToHide.Count > 0)
|
||||
// 核心修复:使用与 ModelSplitterManager.ExportLayerToNwd 相同的精确隔离逻辑
|
||||
// 在主线程中执行 Navisworks API 调用
|
||||
System.Windows.Application.Current.Dispatcher.Invoke(() =>
|
||||
{
|
||||
try
|
||||
{
|
||||
document.Models.SetHidden(itemsToHide, true);
|
||||
LogManager.Info($"[LayerManagementViewModel] 成功隐藏 {hiddenCount} 个节点,保留 {nodesToKeepVisible.Count} 个选中节点及其相关节点可见");
|
||||
LogManager.Info($"[LayerManagementViewModel] 在主线程中执行导出操作");
|
||||
|
||||
// 保存当前可见性状态
|
||||
LogManager.Info($"[LayerManagementViewModel] 开始保存当前可见性状态");
|
||||
var originalVisibilityState = SaveCurrentVisibilityState(document);
|
||||
LogManager.Info($"[LayerManagementViewModel] 已保存可见性状态");
|
||||
|
||||
try
|
||||
{
|
||||
// 使用 VisibilityHelper.IsolateSpecificItems 精确隔离显示
|
||||
// 这个方法已经在分层导出中验证有效,不会包含额外的祖先节点
|
||||
LogManager.Info($"[LayerManagementViewModel] 准备隔离显示 {itemsToExport.Count} 个节点");
|
||||
|
||||
// 将 List<ModelItem> 转换为 ModelItemCollection
|
||||
var itemsToIsolate = new ModelItemCollection();
|
||||
foreach (var item in itemsToExport)
|
||||
{
|
||||
itemsToIsolate.Add(item);
|
||||
}
|
||||
|
||||
bool isolateSuccess = VisibilityHelper.IsolateSpecificItems(itemsToIsolate);
|
||||
|
||||
if (!isolateSuccess)
|
||||
{
|
||||
throw new InvalidOperationException("隔离显示失败");
|
||||
}
|
||||
|
||||
LogManager.Info($"[LayerManagementViewModel] 隔离显示成功");
|
||||
|
||||
// 创建导出选项 - 使用用户配置的参数
|
||||
var exportOptions = new Autodesk.Navisworks.Api.NwdExportOptions
|
||||
{
|
||||
ExcludeHiddenItems = true, // 只导出可见项目(选中节点及其子项)
|
||||
EmbedXrefs = EmbedXrefs,
|
||||
PreventObjectPropertyExport = PreventObjectPropertyExport
|
||||
};
|
||||
|
||||
LogManager.Info($"[LayerManagementViewModel] SaveSelectedItems导出选项: EmbedXrefs={exportOptions.EmbedXrefs}, PreventObjectPropertyExport={exportOptions.PreventObjectPropertyExport}");
|
||||
LogManager.Info("[LayerManagementViewModel] 开始调用ExportToNwd API");
|
||||
|
||||
// 使用ExportToNwd API
|
||||
document.ExportToNwd(saveFilePath, exportOptions);
|
||||
|
||||
exportResult = true;
|
||||
LogManager.Info("[LayerManagementViewModel] ExportToNwd API调用完成");
|
||||
}
|
||||
finally
|
||||
{
|
||||
// 恢复原始可见性状态
|
||||
try
|
||||
{
|
||||
RestoreVisibilityState(document, originalVisibilityState);
|
||||
LogManager.Info("[LayerManagementViewModel] 已恢复原始可见性状态");
|
||||
}
|
||||
catch (Exception restoreEx)
|
||||
{
|
||||
LogManager.Error($"[LayerManagementViewModel] 恢复可见性失败: {restoreEx.Message}");
|
||||
}
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
LogManager.Warning($"[LayerManagementViewModel] 隐藏操作失败: {ex.Message}");
|
||||
LogManager.Error($"[LayerManagementViewModel] 主线程导出异常: {ex.Message}", ex);
|
||||
errorMessage = ex.Message;
|
||||
exportResult = false;
|
||||
}
|
||||
}
|
||||
|
||||
// 确保选中所有目标节点
|
||||
document.CurrentSelection.Clear();
|
||||
foreach (var selectedItem in originalSelection)
|
||||
{
|
||||
document.CurrentSelection.Add(selectedItem);
|
||||
}
|
||||
LogManager.Info($"[LayerManagementViewModel] 已重新选择 {originalSelection.Count} 个目标节点");
|
||||
|
||||
// 创建导出选项 - 使用用户配置的参数
|
||||
var exportOptions = new Autodesk.Navisworks.Api.NwdExportOptions
|
||||
{
|
||||
ExcludeHiddenItems = true, // 只导出可见项目(选中节点及其子项)
|
||||
EmbedXrefs = EmbedXrefs,
|
||||
PreventObjectPropertyExport = PreventObjectPropertyExport
|
||||
};
|
||||
|
||||
LogManager.Info($"[LayerManagementViewModel] SaveSelectedItems导出选项: EmbedXrefs={exportOptions.EmbedXrefs}, PreventObjectPropertyExport={exportOptions.PreventObjectPropertyExport}");
|
||||
|
||||
LogManager.Info("[LayerManagementViewModel] 开始调用ExportToNwd API");
|
||||
|
||||
// 使用ExportToNwd API
|
||||
document.ExportToNwd(saveFilePath, exportOptions);
|
||||
|
||||
exportResult = true;
|
||||
LogManager.Info("[LayerManagementViewModel] ExportToNwd API调用完成");
|
||||
|
||||
// 恢复所有隐藏项目的可见性
|
||||
try
|
||||
{
|
||||
if (document?.Models != null)
|
||||
{
|
||||
// 获取所有模型项并恢复可见性
|
||||
var allItems = new ModelItemCollection();
|
||||
foreach (Model model in document.Models)
|
||||
{
|
||||
foreach (ModelItem item in model.RootItem.Children)
|
||||
{
|
||||
allItems.Add(item);
|
||||
}
|
||||
}
|
||||
|
||||
if (allItems.Count > 0)
|
||||
{
|
||||
document.Models.SetHidden(allItems, false);
|
||||
LogManager.Info("[LayerManagementViewModel] 已恢复所有项目可见性");
|
||||
}
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
LogManager.Warning($"[LayerManagementViewModel] 恢复可见性失败: {ex.Message}");
|
||||
}
|
||||
});
|
||||
|
||||
// 恢复原始选择
|
||||
try
|
||||
@ -2110,6 +2039,110 @@ namespace NavisworksTransport.UI.WPF.ViewModels
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 保存当前可见性状态
|
||||
/// </summary>
|
||||
private Dictionary<ModelItem, bool> SaveCurrentVisibilityState(Document document)
|
||||
{
|
||||
var visibilityState = new Dictionary<ModelItem, bool>();
|
||||
|
||||
try
|
||||
{
|
||||
// 获取所有顶级项目并记录它们的可见性状态
|
||||
foreach (Model model in document.Models)
|
||||
{
|
||||
foreach (ModelItem topLevelItem in model.RootItem.Children)
|
||||
{
|
||||
try
|
||||
{
|
||||
// 记录是否隐藏(IsHidden为true表示隐藏,我们存储可见性所以取反)
|
||||
visibilityState[topLevelItem] = !topLevelItem.IsHidden;
|
||||
}
|
||||
catch
|
||||
{
|
||||
// 如果无法获取状态,默认为可见
|
||||
visibilityState[topLevelItem] = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
LogManager.Info($"[LayerManagementViewModel] 保存可见性状态完成,记录了 {visibilityState.Count} 个顶级项目");
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
LogManager.Error($"[LayerManagementViewModel] 保存可见性状态失败: {ex.Message}");
|
||||
}
|
||||
|
||||
return visibilityState;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 恢复可见性状态
|
||||
/// </summary>
|
||||
private void RestoreVisibilityState(Document document, Dictionary<ModelItem, bool> visibilityState)
|
||||
{
|
||||
try
|
||||
{
|
||||
LogManager.Info("[LayerManagementViewModel] 恢复可见性状态");
|
||||
|
||||
if (visibilityState == null || visibilityState.Count == 0)
|
||||
{
|
||||
LogManager.Warning("[LayerManagementViewModel] 没有可见性状态需要恢复,重置为全部可见");
|
||||
document.Models.ResetAllHidden();
|
||||
return;
|
||||
}
|
||||
|
||||
// 使用成熟的可见性控制模式 - 分别收集要显示和隐藏的项目
|
||||
var itemsToShow = new ModelItemCollection();
|
||||
var itemsToHide = new ModelItemCollection();
|
||||
|
||||
foreach (var kvp in visibilityState)
|
||||
{
|
||||
try
|
||||
{
|
||||
if (kvp.Value) // 原来是可见的
|
||||
{
|
||||
itemsToShow.Add(kvp.Key);
|
||||
}
|
||||
else // 原来是隐藏的
|
||||
{
|
||||
itemsToHide.Add(kvp.Key);
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
LogManager.Warning($"[LayerManagementViewModel] 处理项目可见性状态时出错: {ex.Message}");
|
||||
}
|
||||
}
|
||||
|
||||
// 首先重置所有项目为可见状态
|
||||
document.Models.ResetAllHidden();
|
||||
|
||||
// 然后隐藏原来应该隐藏的项目
|
||||
if (itemsToHide.Count > 0)
|
||||
{
|
||||
document.Models.SetHidden(itemsToHide, true);
|
||||
LogManager.Info($"[LayerManagementViewModel] 恢复隐藏 {itemsToHide.Count} 个项目");
|
||||
}
|
||||
|
||||
LogManager.Info("[LayerManagementViewModel] 可见性状态恢复完成");
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
LogManager.Error($"[LayerManagementViewModel] 恢复可见性状态失败: {ex.Message}");
|
||||
// 失败时至少确保模型处于可见状态
|
||||
try
|
||||
{
|
||||
document.Models.ResetAllHidden();
|
||||
LogManager.Info("[LayerManagementViewModel] 已重置为全部可见状态");
|
||||
}
|
||||
catch (Exception resetEx)
|
||||
{
|
||||
LogManager.Error($"[LayerManagementViewModel] 重置可见性也失败: {resetEx.Message}");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
/// <summary>
|
||||
|
||||
Loading…
Reference in New Issue
Block a user