简化可见性控制代码,改成工具类
This commit is contained in:
parent
0195d3e8ad
commit
fc0b6d6aaa
@ -106,7 +106,6 @@
|
||||
<Compile Include="src\Core\PathDataManager.cs" />
|
||||
<Compile Include="src\Core\PathPlanningManager.cs" />
|
||||
<Compile Include="src\Core\PathPlanningModels.cs" />
|
||||
<Compile Include="src\Core\VisibilityManager.cs" />
|
||||
|
||||
<!-- Core - Events and Interfaces -->
|
||||
<Compile Include="src\Core\IPathPlanningManagerEvents.cs" />
|
||||
@ -247,6 +246,7 @@
|
||||
<Compile Include="src\Utils\NavisworksApiHelper.cs" />
|
||||
<Compile Include="src\Utils\NavisworksSelectionHelper.cs" />
|
||||
<Compile Include="src\Utils\UnitsConverter.cs" />
|
||||
<Compile Include="src\Utils\VisibilityHelper.cs" />
|
||||
|
||||
<!-- Assembly Info -->
|
||||
<Compile Include="Properties\AssemblyInfo.cs" />
|
||||
|
||||
@ -2,6 +2,16 @@
|
||||
|
||||
## 功能点
|
||||
|
||||
### [2025/09/12]
|
||||
|
||||
1. [x] (功能)给动画增加步进功能,同时提供反向功能(反向播放、反向步进)
|
||||
2. [x] (功能) 自动生成的路径,贴合通道表面
|
||||
|
||||
### [2025/09/011]
|
||||
|
||||
1. [x] (性能优化)大模型文件分层和导出,不挂机不崩溃
|
||||
2. [x] (性能优化) 提高显示/隐藏的性能
|
||||
|
||||
### [2025/09/09]
|
||||
|
||||
1. [x] (功能)增加安全优先路径策略
|
||||
|
||||
@ -1766,15 +1766,14 @@ namespace NavisworksTransport
|
||||
|
||||
// 使用 VisibilityManager.IsolateSpecificItems 隔离显示
|
||||
// 这个方法会使用缓存优化,效率更高
|
||||
var isolateResult = VisibilityManager.IsolateSpecificItems(itemsToIsolate);
|
||||
bool isolateSuccess = VisibilityHelper.IsolateSpecificItems(itemsToIsolate);
|
||||
|
||||
if (!isolateResult.Success)
|
||||
if (!isolateSuccess)
|
||||
{
|
||||
throw new InvalidOperationException($"隔离显示失败: {isolateResult.Message}");
|
||||
throw new InvalidOperationException("隔离显示失败");
|
||||
}
|
||||
|
||||
LogManager.Info($"[分层管理器] 隔离显示成功: {isolateResult.Message}");
|
||||
LogManager.Info($"[分层管理器] 隐藏了 {isolateResult.HiddenCount} 个项目,保持 {isolateResult.TotalCount - isolateResult.HiddenCount} 个项目可见");
|
||||
LogManager.Info($"[分层管理器] 隔离显示成功");
|
||||
|
||||
// 创建导出选项
|
||||
var exportOptions = new Autodesk.Navisworks.Api.NwdExportOptions
|
||||
|
||||
@ -21,7 +21,6 @@ namespace NavisworksTransport
|
||||
|
||||
private readonly string _managerId;
|
||||
private readonly CategoryAttributeManager _categoryManager;
|
||||
private readonly VisibilityManager _visibilityManager;
|
||||
private readonly UIStateManager _uiStateManager;
|
||||
|
||||
private CoordinateConverter _coordinateConverter;
|
||||
@ -83,13 +82,11 @@ namespace NavisworksTransport
|
||||
/// 构造函数
|
||||
/// </summary>
|
||||
/// <param name="categoryManager">类别属性管理器</param>
|
||||
/// <param name="visibilityManager">可见性管理器</param>
|
||||
/// <param name="uiStateManager">UI状态管理器(可选)</param>
|
||||
public PathPlanningManager(CategoryAttributeManager categoryManager, VisibilityManager visibilityManager, UIStateManager uiStateManager = null)
|
||||
public PathPlanningManager(CategoryAttributeManager categoryManager, UIStateManager uiStateManager = null)
|
||||
{
|
||||
_managerId = Guid.NewGuid().ToString("N").Substring(0, 8); // 前8位作为ID
|
||||
_categoryManager = categoryManager ?? throw new ArgumentNullException(nameof(categoryManager));
|
||||
_visibilityManager = visibilityManager ?? throw new ArgumentNullException(nameof(visibilityManager));
|
||||
_uiStateManager = uiStateManager ?? UIStateManager.Instance;
|
||||
|
||||
InitializeManager();
|
||||
@ -102,7 +99,6 @@ namespace NavisworksTransport
|
||||
{
|
||||
_managerId = Guid.NewGuid().ToString("N").Substring(0, 8);
|
||||
_categoryManager = new CategoryAttributeManager();
|
||||
_visibilityManager = new VisibilityManager();
|
||||
_uiStateManager = UIStateManager.Instance;
|
||||
|
||||
InitializeManager();
|
||||
@ -1988,9 +1984,6 @@ namespace NavisworksTransport
|
||||
if (_categoryManager == null)
|
||||
errors.Add("类别属性管理器未初始化");
|
||||
|
||||
if (_visibilityManager == null)
|
||||
errors.Add("可见性管理器未初始化");
|
||||
|
||||
if (_uiStateManager == null)
|
||||
errors.Add("UI状态管理器未初始化");
|
||||
|
||||
|
||||
@ -1,937 +0,0 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.ComponentModel;
|
||||
using System.Linq;
|
||||
using Autodesk.Navisworks.Api;
|
||||
using NavisApplication = Autodesk.Navisworks.Api.Application;
|
||||
|
||||
namespace NavisworksTransport
|
||||
{
|
||||
/// <summary>
|
||||
/// 可见性操作结果
|
||||
/// </summary>
|
||||
public class VisibilityOperationResult
|
||||
{
|
||||
/// <summary>
|
||||
/// 操作是否成功
|
||||
/// </summary>
|
||||
public bool Success { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 结果消息
|
||||
/// </summary>
|
||||
public string Message { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 隐藏的项目数量
|
||||
/// </summary>
|
||||
public int HiddenCount { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 模型总项目数量
|
||||
/// </summary>
|
||||
public int TotalCount { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 错误信息列表
|
||||
/// </summary>
|
||||
public List<string> Errors { get; set; } = new List<string>();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 可见性统计信息
|
||||
/// </summary>
|
||||
public class VisibilityStatistics
|
||||
{
|
||||
/// <summary>
|
||||
/// 模型总项目数量
|
||||
/// </summary>
|
||||
public int TotalModelItems { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 具有物流分类的项目数量
|
||||
/// </summary>
|
||||
public int LogisticsItems { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 没有物流分类的项目数量
|
||||
/// </summary>
|
||||
public int NonLogisticsItems { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 当前隐藏的项目数量
|
||||
/// </summary>
|
||||
public int HiddenItems { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 当前可见的项目数量
|
||||
/// </summary>
|
||||
public int VisibleItems { get; set; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 可见性管理器
|
||||
/// 负责ModelItem可见性控制的核心业务逻辑
|
||||
/// </summary>
|
||||
public class VisibilityManager
|
||||
{
|
||||
#region 私有字段
|
||||
|
||||
private readonly Document _document;
|
||||
private List<ModelItem> _lastHiddenItems; // 缓存最后一次隐藏的项目列表
|
||||
|
||||
#endregion
|
||||
|
||||
#region 事件
|
||||
|
||||
/// <summary>
|
||||
/// 进度报告事件
|
||||
/// </summary>
|
||||
public event EventHandler<ProgressChangedEventArgs> ProgressChanged;
|
||||
|
||||
/// <summary>
|
||||
/// 操作完成事件
|
||||
/// </summary>
|
||||
public event EventHandler<VisibilityOperationResult> OperationCompleted;
|
||||
|
||||
#endregion
|
||||
|
||||
#region 构造函数
|
||||
|
||||
/// <summary>
|
||||
/// 初始化可见性管理器
|
||||
/// </summary>
|
||||
public VisibilityManager()
|
||||
{
|
||||
_document = NavisApplication.ActiveDocument;
|
||||
_lastHiddenItems = new List<ModelItem>();
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region 静态方法
|
||||
|
||||
/// <summary>
|
||||
/// 检查ModelItem或其任何子项是否包含物流属性
|
||||
/// </summary>
|
||||
/// <param name="item">要检查的ModelItem</param>
|
||||
/// <returns>如果本身或任何子项包含物流属性则返回true</returns>
|
||||
private static bool HasLogisticsAttributesRecursive(ModelItem item)
|
||||
{
|
||||
// 首先检查当前项目
|
||||
if (CategoryAttributeManager.HasLogisticsAttributes(item))
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
// 然后递归检查子项目
|
||||
if (item.Children != null && item.Children.Count() > 0)
|
||||
{
|
||||
foreach (ModelItem child in item.Children)
|
||||
{
|
||||
if (HasLogisticsAttributesRecursive(child))
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 静态方法:隐藏非物流分类项目(优化版,只处理顶级节点)
|
||||
/// </summary>
|
||||
/// <returns>操作结果</returns>
|
||||
public static VisibilityOperationResult HideNonLogisticsItems()
|
||||
{
|
||||
try
|
||||
{
|
||||
var stopwatch = System.Diagnostics.Stopwatch.StartNew();
|
||||
|
||||
var document = NavisApplication.ActiveDocument;
|
||||
if (document == null || document.Models.Count == 0)
|
||||
{
|
||||
return new VisibilityOperationResult { Success = true, Message = "没有加载的模型" };
|
||||
}
|
||||
|
||||
LogManager.Debug("[VisibilityManager] HideNonLogisticsItems - 开始隐藏非物流项目");
|
||||
|
||||
// 先重置所有内容为可见,确保从干净状态开始
|
||||
document.Models.ResetAllHidden();
|
||||
|
||||
// 只处理顶级节点,大幅提升性能
|
||||
var rootItems = new List<ModelItem>();
|
||||
var itemsToHide = new ModelItemCollection();
|
||||
int logisticsCount = 0;
|
||||
int nonLogisticsCount = 0;
|
||||
|
||||
// 遍历所有模型的第一级子节点
|
||||
foreach (Model model in document.Models)
|
||||
{
|
||||
if (model.RootItem != null && model.RootItem.Children != null)
|
||||
{
|
||||
foreach (ModelItem topLevelItem in model.RootItem.Children)
|
||||
{
|
||||
rootItems.Add(topLevelItem);
|
||||
|
||||
// 检查该顶级节点或其子节点是否包含物流属性
|
||||
if (!HasLogisticsAttributesRecursive(topLevelItem))
|
||||
{
|
||||
itemsToHide.Add(topLevelItem);
|
||||
nonLogisticsCount++;
|
||||
LogManager.Debug($"[VisibilityManager] 隐藏非物流节点: {topLevelItem.DisplayName}");
|
||||
}
|
||||
else
|
||||
{
|
||||
logisticsCount++;
|
||||
LogManager.Debug($"[VisibilityManager] 保持物流节点可见: {topLevelItem.DisplayName}");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 执行隐藏操作
|
||||
if (itemsToHide.Count > 0)
|
||||
{
|
||||
var hideStopwatch = System.Diagnostics.Stopwatch.StartNew();
|
||||
document.Models.SetHidden(itemsToHide, true);
|
||||
hideStopwatch.Stop();
|
||||
LogManager.Debug($"[VisibilityManager] 隐藏操作耗时 {hideStopwatch.ElapsedMilliseconds}ms");
|
||||
}
|
||||
|
||||
stopwatch.Stop();
|
||||
|
||||
// 使用已知的总节点数或估算
|
||||
int totalItemsCount = 17699; // 使用已知值
|
||||
int estimatedHiddenCount = nonLogisticsCount * 1000; // 估算每个顶级节点包含的子节点数
|
||||
|
||||
LogManager.Info($"[VisibilityManager] HideNonLogisticsItems完成: " +
|
||||
$"顶级节点 {rootItems.Count} 个, " +
|
||||
$"物流节点 {logisticsCount} 个, " +
|
||||
$"隐藏节点 {nonLogisticsCount} 个, " +
|
||||
$"耗时 {stopwatch.ElapsedMilliseconds}ms");
|
||||
|
||||
return new VisibilityOperationResult
|
||||
{
|
||||
Success = true,
|
||||
Message = $"成功隐藏 {nonLogisticsCount} 个非物流顶级节点",
|
||||
HiddenCount = estimatedHiddenCount,
|
||||
TotalCount = totalItemsCount
|
||||
};
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
LogManager.Error($"[VisibilityManager] HideNonLogisticsItems失败: {ex.Message}");
|
||||
return new VisibilityOperationResult
|
||||
{
|
||||
Success = false,
|
||||
Message = $"操作失败: {ex.Message}",
|
||||
HiddenCount = 0,
|
||||
TotalCount = 0,
|
||||
Errors = { ex.Message }
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 统一的重置可见性方法 - 显示所有项目并清理缓存
|
||||
/// </summary>
|
||||
/// <param name="clearCache">是否清除缓存,默认为true</param>
|
||||
/// <returns>操作结果</returns>
|
||||
public static VisibilityOperationResult ResetVisibility(bool clearCache = true)
|
||||
{
|
||||
try
|
||||
{
|
||||
var stopwatch = System.Diagnostics.Stopwatch.StartNew();
|
||||
|
||||
var document = NavisApplication.ActiveDocument;
|
||||
if (document == null || document.Models.Count == 0)
|
||||
{
|
||||
return new VisibilityOperationResult
|
||||
{
|
||||
Success = true,
|
||||
Message = "没有加载的模型"
|
||||
};
|
||||
}
|
||||
|
||||
LogManager.Debug("[VisibilityManager] ResetVisibility - 重置所有可见性状态");
|
||||
|
||||
// 重置所有隐藏状态
|
||||
document.Models.ResetAllHidden();
|
||||
|
||||
// 不再需要清除缓存
|
||||
|
||||
stopwatch.Stop();
|
||||
LogManager.Info($"[VisibilityManager] ResetVisibility完成,耗时 {stopwatch.ElapsedMilliseconds}ms");
|
||||
|
||||
return new VisibilityOperationResult
|
||||
{
|
||||
Success = true,
|
||||
Message = "可见性已重置,所有项目已显示",
|
||||
HiddenCount = 0,
|
||||
TotalCount = 17699 // 使用已知值
|
||||
};
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
LogManager.Error($"[VisibilityManager] ResetVisibility失败: {ex.Message}");
|
||||
return new VisibilityOperationResult
|
||||
{
|
||||
Success = false,
|
||||
Message = $"重置可见性失败: {ex.Message}",
|
||||
HiddenCount = 0,
|
||||
TotalCount = 0,
|
||||
Errors = { ex.Message }
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 静态方法:显示所有项目(优化版,利用缓存)
|
||||
/// </summary>
|
||||
/// <returns>操作结果</returns>
|
||||
public static VisibilityOperationResult ShowAllItems()
|
||||
{
|
||||
try
|
||||
{
|
||||
var stopwatch = System.Diagnostics.Stopwatch.StartNew();
|
||||
|
||||
var document = NavisApplication.ActiveDocument;
|
||||
if (document == null || document.Models.Count == 0)
|
||||
{
|
||||
return new VisibilityOperationResult { Success = true, Message = "没有加载的模型" };
|
||||
}
|
||||
|
||||
// 使用 ResetAllHidden 确保所有项目都被显示
|
||||
document.Models.ResetAllHidden();
|
||||
|
||||
// 快速统计
|
||||
int totalItemsCount = 17699; // 已知的节点总数
|
||||
|
||||
stopwatch.Stop();
|
||||
LogManager.Info($"[VisibilityManager] ShowAllItems完成,耗时 {stopwatch.ElapsedMilliseconds}ms");
|
||||
|
||||
return new VisibilityOperationResult
|
||||
{
|
||||
Success = true,
|
||||
Message = "所有项目已显示",
|
||||
HiddenCount = 0, // 重置后,隐藏数量必为0
|
||||
TotalCount = totalItemsCount
|
||||
};
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
LogManager.Error($"[VisibilityManager] ShowAllItems失败: {ex.Message}");
|
||||
return new VisibilityOperationResult
|
||||
{
|
||||
Success = false,
|
||||
Message = $"显示操作失败: {ex.Message}",
|
||||
HiddenCount = 0,
|
||||
TotalCount = 0,
|
||||
Errors = { ex.Message }
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 仅显示指定的模型项集合,隐藏其他所有项
|
||||
/// 针对分层场景优化:当输入是少量根节点时,不遍历Descendants
|
||||
/// </summary>
|
||||
/// <param name="itemsToShow">要显示的模型项集合</param>
|
||||
/// <returns>操作结果</returns>
|
||||
public static VisibilityOperationResult IsolateSpecificItems(ModelItemCollection itemsToShow)
|
||||
{
|
||||
try
|
||||
{
|
||||
var stopwatch = System.Diagnostics.Stopwatch.StartNew();
|
||||
|
||||
var document = NavisApplication.ActiveDocument;
|
||||
if (document == null || document.Models.Count == 0)
|
||||
{
|
||||
return new VisibilityOperationResult
|
||||
{
|
||||
Success = false,
|
||||
Message = "没有加载的模型"
|
||||
};
|
||||
}
|
||||
|
||||
if (itemsToShow == null || !itemsToShow.Any())
|
||||
{
|
||||
return new VisibilityOperationResult
|
||||
{
|
||||
Success = false,
|
||||
Message = "没有指定要显示的项目"
|
||||
};
|
||||
}
|
||||
|
||||
LogManager.Debug($"[VisibilityManager] 开始隔离显示 {itemsToShow.Count} 个项目");
|
||||
|
||||
// 1. 重置所有隐藏状态 - 必须从全部可见开始
|
||||
document.Models.ResetAllHidden();
|
||||
|
||||
// 2. 创建可见项集合
|
||||
ModelItemCollection visible = new ModelItemCollection();
|
||||
|
||||
foreach (ModelItem item in itemsToShow)
|
||||
{
|
||||
// 添加祖先路径(确保能看到)
|
||||
if (item.AncestorsAndSelf != null)
|
||||
visible.AddRange(item.AncestorsAndSelf);
|
||||
|
||||
// 不添加Descendants - 父节点可见时子节点会自动可见
|
||||
}
|
||||
|
||||
LogManager.Debug($"[VisibilityManager] 收集可见项完成,共 {visible.Count} 个");
|
||||
|
||||
// 3. 创建隐藏集合 - 收集所有可见项的兄弟节点
|
||||
ModelItemCollection hidden = new ModelItemCollection();
|
||||
|
||||
foreach (ModelItem toShow in visible)
|
||||
{
|
||||
if (toShow.Parent != null)
|
||||
{
|
||||
// 添加父节点的所有子节点
|
||||
hidden.AddRange(toShow.Parent.Children);
|
||||
}
|
||||
}
|
||||
|
||||
// 4. 从隐藏集合中移除可见项
|
||||
foreach (ModelItem toShow in visible)
|
||||
{
|
||||
hidden.Remove(toShow);
|
||||
}
|
||||
|
||||
LogManager.Debug($"[VisibilityManager] 需要隐藏 {hidden.Count} 个项目");
|
||||
|
||||
// 5. 执行隐藏操作
|
||||
if (hidden.Count > 0)
|
||||
{
|
||||
document.Models.SetHidden(hidden, true);
|
||||
}
|
||||
|
||||
stopwatch.Stop();
|
||||
LogManager.Info($"[VisibilityManager] 隔离显示完成,耗时 {stopwatch.ElapsedMilliseconds}ms");
|
||||
|
||||
return new VisibilityOperationResult
|
||||
{
|
||||
Success = true,
|
||||
Message = $"已隔离显示 {itemsToShow.Count} 个项目",
|
||||
HiddenCount = hidden.Count,
|
||||
TotalCount = visible.Count
|
||||
};
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
LogManager.Error($"[VisibilityManager] 隔离显示失败: {ex.Message}");
|
||||
return new VisibilityOperationResult
|
||||
{
|
||||
Success = false,
|
||||
Message = $"隔离显示操作失败: {ex.Message}",
|
||||
HiddenCount = 0,
|
||||
TotalCount = 0,
|
||||
Errors = { ex.Message }
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 静态方法:根据物流类型显示特定项目
|
||||
/// </summary>
|
||||
/// <param name="elementType">要显示的物流元素类型</param>
|
||||
/// <returns>操作结果</returns>
|
||||
public static VisibilityOperationResult ShowLogisticsItemsOnly(CategoryAttributeManager.LogisticsElementType elementType)
|
||||
{
|
||||
try
|
||||
{
|
||||
var document = NavisApplication.ActiveDocument;
|
||||
var allItems = GetAllModelItemsStatic();
|
||||
var itemsToHide = new List<ModelItem>();
|
||||
|
||||
foreach (var item in allItems)
|
||||
{
|
||||
string typeValue = CategoryAttributeManager.GetLogisticsPropertyValue(item, CategoryAttributeManager.LogisticsProperties.TYPE);
|
||||
if (typeValue != elementType.ToString() && !string.IsNullOrEmpty(typeValue))
|
||||
{
|
||||
itemsToHide.Add(item);
|
||||
}
|
||||
}
|
||||
|
||||
// 首先显示所有项目
|
||||
document.Models.ResetAllHidden();
|
||||
|
||||
// 然后隐藏非目标类型的项目
|
||||
if (itemsToHide.Count > 0)
|
||||
{
|
||||
var collection = new ModelItemCollection();
|
||||
foreach (var item in itemsToHide)
|
||||
{
|
||||
collection.Add(item);
|
||||
}
|
||||
document.Models.SetHidden(collection, true);
|
||||
}
|
||||
|
||||
return new VisibilityOperationResult
|
||||
{
|
||||
Success = true,
|
||||
Message = $"仅显示 {elementType} 类型的项目,隐藏了 {itemsToHide.Count} 个其他项目",
|
||||
HiddenCount = itemsToHide.Count,
|
||||
TotalCount = allItems.Count
|
||||
};
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
return new VisibilityOperationResult
|
||||
{
|
||||
Success = false,
|
||||
Message = $"操作失败: {ex.Message}",
|
||||
HiddenCount = 0,
|
||||
TotalCount = 0,
|
||||
Errors = { ex.Message }
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 静态方法:获取模型中的所有ModelItem
|
||||
/// </summary>
|
||||
/// <returns>ModelItem列表</returns>
|
||||
private static List<ModelItem> GetAllModelItemsStatic()
|
||||
{
|
||||
var collection = new List<ModelItem>();
|
||||
var doc = NavisApplication.ActiveDocument;
|
||||
if (doc != null)
|
||||
{
|
||||
foreach (var model in doc.Models)
|
||||
{
|
||||
// 从根模型的子项开始收集,以避免包含不可见的根节点
|
||||
foreach (var item in model.RootItem.Children)
|
||||
{
|
||||
CollectModelItemsStatic(item, collection);
|
||||
}
|
||||
}
|
||||
}
|
||||
return collection;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 静态方法:递归收集ModelItem及其所有子项
|
||||
/// </summary>
|
||||
/// <param name="item">当前ModelItem</param>
|
||||
/// <param name="collection">收集列表</param>
|
||||
private static void CollectModelItemsStatic(ModelItem item, List<ModelItem> collection)
|
||||
{
|
||||
collection.Add(item);
|
||||
foreach (ModelItem child in item.Children)
|
||||
{
|
||||
CollectModelItemsStatic(child, collection);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 递归计算一个模型项及其所有后代的总数
|
||||
/// </summary>
|
||||
/// <param name="item">要计算的模型项</param>
|
||||
/// <returns>总数</returns>
|
||||
private static int CountDescendantsAndSelf(ModelItem item)
|
||||
{
|
||||
var items = new List<ModelItem>();
|
||||
CollectModelItemsStatic(item, items);
|
||||
return items.Count;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 为所有子元素(包括深层嵌套)添加到可见集合中
|
||||
/// </summary>
|
||||
/// <param name="parent">父级ModelItem</param>
|
||||
/// <param name="visibleItems">要更新的可见项集合</param>
|
||||
public static void AddAllChildren(ModelItem parent, HashSet<ModelItem> visibleItems)
|
||||
{
|
||||
if (parent?.Children != null)
|
||||
{
|
||||
foreach (ModelItem child in parent.Children)
|
||||
{
|
||||
visibleItems.Add(child);
|
||||
// 递归添加子元素的子元素
|
||||
AddAllChildren(child, visibleItems);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 向上遍历添加所有父节点到可见集合中(到根节点)
|
||||
/// </summary>
|
||||
/// <param name="item">起始ModelItem</param>
|
||||
/// <param name="visibleItems">要更新的可见项集合</param>
|
||||
public static void AddAllParents(ModelItem item, HashSet<ModelItem> visibleItems)
|
||||
{
|
||||
var parent = item?.Parent;
|
||||
while (parent != null)
|
||||
{
|
||||
visibleItems.Add(parent);
|
||||
parent = parent.Parent;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 构建完整的保护集合,包括指定项目、其父节点路径和所有子节点
|
||||
/// </summary>
|
||||
/// <param name="itemsToShow">需要保持可见的核心项目集合</param>
|
||||
/// <returns>包含完整可见性保护路径的集合</returns>
|
||||
public static HashSet<ModelItem> BuildProtectionSet(IEnumerable<ModelItem> itemsToShow)
|
||||
{
|
||||
var protectionSet = new HashSet<ModelItem>();
|
||||
|
||||
foreach (var item in itemsToShow)
|
||||
{
|
||||
if (item != null)
|
||||
{
|
||||
// 添加项目本身
|
||||
protectionSet.Add(item);
|
||||
|
||||
// 添加所有父节点路径(向上到根节点)
|
||||
AddAllParents(item, protectionSet);
|
||||
|
||||
// 添加所有子节点(向下递归)
|
||||
AddAllChildren(item, protectionSet);
|
||||
}
|
||||
}
|
||||
|
||||
return protectionSet;
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region 实例方法
|
||||
|
||||
/// <summary>
|
||||
/// 异步隐藏非物流分类项目
|
||||
/// </summary>
|
||||
public void HideNonLogisticsItemsAsync()
|
||||
{
|
||||
BackgroundWorker worker = new BackgroundWorker();
|
||||
worker.WorkerReportsProgress = true;
|
||||
worker.WorkerSupportsCancellation = true;
|
||||
|
||||
worker.DoWork += (sender, e) =>
|
||||
{
|
||||
try
|
||||
{
|
||||
var allItems = GetAllModelItems();
|
||||
var itemsToHide = new List<ModelItem>();
|
||||
|
||||
for (int i = 0; i < allItems.Count; i++)
|
||||
{
|
||||
if (worker.CancellationPending)
|
||||
{
|
||||
e.Cancel = true;
|
||||
break;
|
||||
}
|
||||
|
||||
if (!CategoryAttributeManager.HasLogisticsAttributes(allItems[i]))
|
||||
{
|
||||
itemsToHide.Add(allItems[i]);
|
||||
}
|
||||
|
||||
// 报告进度
|
||||
int progress = (i * 100) / allItems.Count;
|
||||
worker.ReportProgress(progress);
|
||||
}
|
||||
|
||||
e.Result = new VisibilityOperationResult
|
||||
{
|
||||
Success = !e.Cancel,
|
||||
HiddenCount = itemsToHide.Count,
|
||||
TotalCount = allItems.Count,
|
||||
Message = e.Cancel ? "操作已取消" : $"成功隐藏 {itemsToHide.Count} 个非物流分类项目"
|
||||
};
|
||||
|
||||
// 缓存隐藏的项目列表
|
||||
if (!e.Cancel)
|
||||
{
|
||||
_lastHiddenItems = itemsToHide;
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
e.Result = new VisibilityOperationResult
|
||||
{
|
||||
Success = false,
|
||||
Message = $"操作失败: {ex.Message}",
|
||||
HiddenCount = 0,
|
||||
TotalCount = 0
|
||||
};
|
||||
}
|
||||
};
|
||||
|
||||
worker.ProgressChanged += (sender, e) =>
|
||||
{
|
||||
ProgressChanged?.Invoke(this, e);
|
||||
};
|
||||
|
||||
worker.RunWorkerCompleted += (sender, e) =>
|
||||
{
|
||||
var result = (VisibilityOperationResult)e.Result;
|
||||
|
||||
if (result.Success && result.HiddenCount > 0)
|
||||
{
|
||||
// 执行隐藏操作
|
||||
try
|
||||
{
|
||||
var collection = new ModelItemCollection();
|
||||
foreach (var item in _lastHiddenItems)
|
||||
{
|
||||
collection.Add(item);
|
||||
}
|
||||
_document.Models.SetHidden(collection, true);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
result.Success = false;
|
||||
result.Message = $"隐藏操作失败: {ex.Message}";
|
||||
result.Errors.Add(ex.Message);
|
||||
}
|
||||
}
|
||||
|
||||
OperationCompleted?.Invoke(this, result);
|
||||
};
|
||||
|
||||
worker.RunWorkerAsync();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 实例方法:同步隐藏非物流分类项目(用于小型模型)
|
||||
/// </summary>
|
||||
/// <returns>操作结果</returns>
|
||||
public VisibilityOperationResult HideNonLogisticsItemsInstance()
|
||||
{
|
||||
try
|
||||
{
|
||||
var allItems = GetAllModelItems();
|
||||
var itemsToHide = new List<ModelItem>();
|
||||
|
||||
foreach (var item in allItems)
|
||||
{
|
||||
if (!CategoryAttributeManager.HasLogisticsAttributes(item))
|
||||
{
|
||||
itemsToHide.Add(item);
|
||||
}
|
||||
}
|
||||
|
||||
if (itemsToHide.Count > 0)
|
||||
{
|
||||
var collection = new ModelItemCollection();
|
||||
foreach (var item in itemsToHide)
|
||||
{
|
||||
collection.Add(item);
|
||||
}
|
||||
_document.Models.SetHidden(collection, true);
|
||||
_lastHiddenItems = itemsToHide;
|
||||
}
|
||||
|
||||
return new VisibilityOperationResult
|
||||
{
|
||||
Success = true,
|
||||
Message = $"成功隐藏 {itemsToHide.Count} 个非物流分类项目",
|
||||
HiddenCount = itemsToHide.Count,
|
||||
TotalCount = allItems.Count
|
||||
};
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
return new VisibilityOperationResult
|
||||
{
|
||||
Success = false,
|
||||
Message = $"操作失败: {ex.Message}",
|
||||
HiddenCount = 0,
|
||||
TotalCount = 0,
|
||||
Errors = { ex.Message }
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 实例方法:显示所有项目
|
||||
/// </summary>
|
||||
/// <returns>操作结果</returns>
|
||||
public VisibilityOperationResult ShowAllItemsInstance()
|
||||
{
|
||||
try
|
||||
{
|
||||
_document.Models.ResetAllHidden();
|
||||
|
||||
var totalCount = GetAllModelItems().Count;
|
||||
_lastHiddenItems.Clear();
|
||||
|
||||
return new VisibilityOperationResult
|
||||
{
|
||||
Success = true,
|
||||
Message = "所有项目已显示",
|
||||
HiddenCount = 0,
|
||||
TotalCount = totalCount
|
||||
};
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
return new VisibilityOperationResult
|
||||
{
|
||||
Success = false,
|
||||
Message = $"显示操作失败: {ex.Message}",
|
||||
HiddenCount = _lastHiddenItems.Count,
|
||||
TotalCount = 0,
|
||||
Errors = { ex.Message }
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 获取当前可见性统计信息(静态方法)
|
||||
/// </summary>
|
||||
/// <returns>可见性统计信息</returns>
|
||||
public static VisibilityStatistics GetCurrentStatisticsStatic()
|
||||
{
|
||||
try
|
||||
{
|
||||
var document = NavisApplication.ActiveDocument;
|
||||
if (document == null || document.Models.Count == 0)
|
||||
{
|
||||
return new VisibilityStatistics();
|
||||
}
|
||||
|
||||
// 快速统计可见/隐藏项
|
||||
int hiddenCount = 0;
|
||||
int visibleCount = 0;
|
||||
int logisticsCount = 0;
|
||||
|
||||
// 只检查顶级节点(性能优化)
|
||||
foreach (Model model in document.Models)
|
||||
{
|
||||
if (model.RootItem != null && model.RootItem.Children != null)
|
||||
{
|
||||
foreach (ModelItem topLevelItem in model.RootItem.Children)
|
||||
{
|
||||
if (topLevelItem.IsHidden)
|
||||
{
|
||||
hiddenCount++;
|
||||
}
|
||||
else
|
||||
{
|
||||
visibleCount++;
|
||||
if (HasLogisticsAttributesRecursive(topLevelItem))
|
||||
{
|
||||
logisticsCount++;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
int totalItems = 17699; // 使用已知值
|
||||
|
||||
LogManager.Debug($"[VisibilityManager] 统计信息: 总计{totalItems}, 可见{visibleCount}, 隐藏{hiddenCount}, 物流{logisticsCount}");
|
||||
|
||||
return new VisibilityStatistics
|
||||
{
|
||||
TotalModelItems = totalItems,
|
||||
LogisticsItems = logisticsCount * 1000, // 估算值
|
||||
NonLogisticsItems = totalItems - logisticsCount * 1000,
|
||||
HiddenItems = hiddenCount * 1000, // 估算值
|
||||
VisibleItems = visibleCount * 1000 // 估算值
|
||||
};
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
LogManager.Error($"[VisibilityManager] 获取统计信息失败: {ex.Message}");
|
||||
return new VisibilityStatistics();
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 获取当前可见性统计信息(实例方法)
|
||||
/// </summary>
|
||||
/// <returns>可见性统计信息</returns>
|
||||
public VisibilityStatistics GetCurrentStatistics()
|
||||
{
|
||||
try
|
||||
{
|
||||
var allItems = GetAllModelItems();
|
||||
var logisticsCount = 0;
|
||||
|
||||
foreach (var item in allItems)
|
||||
{
|
||||
if (CategoryAttributeManager.HasLogisticsAttributes(item))
|
||||
{
|
||||
logisticsCount++;
|
||||
}
|
||||
}
|
||||
|
||||
return new VisibilityStatistics
|
||||
{
|
||||
TotalModelItems = allItems.Count,
|
||||
LogisticsItems = logisticsCount,
|
||||
NonLogisticsItems = allItems.Count - logisticsCount,
|
||||
HiddenItems = _lastHiddenItems.Count,
|
||||
VisibleItems = allItems.Count - _lastHiddenItems.Count
|
||||
};
|
||||
}
|
||||
catch (Exception)
|
||||
{
|
||||
// 异常情况返回空统计
|
||||
return new VisibilityStatistics();
|
||||
}
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region 私有方法
|
||||
|
||||
/// <summary>
|
||||
/// 获取模型中的所有ModelItem
|
||||
/// </summary>
|
||||
/// <returns>ModelItem列表</returns>
|
||||
private List<ModelItem> GetAllModelItems()
|
||||
{
|
||||
var allItems = new List<ModelItem>();
|
||||
|
||||
try
|
||||
{
|
||||
// 遍历所有根级ModelItem
|
||||
foreach (ModelItem rootItem in _document.Models.RootItems)
|
||||
{
|
||||
CollectModelItems(rootItem, allItems);
|
||||
}
|
||||
}
|
||||
catch (Exception)
|
||||
{
|
||||
// 如果遍历失败,返回空列表
|
||||
return new List<ModelItem>();
|
||||
}
|
||||
|
||||
return allItems;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 递归收集ModelItem及其所有子项
|
||||
/// </summary>
|
||||
/// <param name="item">当前ModelItem</param>
|
||||
/// <param name="collection">收集列表</param>
|
||||
private void CollectModelItems(ModelItem item, List<ModelItem> collection)
|
||||
{
|
||||
if (item == null) return;
|
||||
|
||||
// 添加当前项目
|
||||
collection.Add(item);
|
||||
|
||||
// 递归添加子项目
|
||||
if (item.Children != null && item.Children.Count() > 0)
|
||||
{
|
||||
foreach (ModelItem child in item.Children)
|
||||
{
|
||||
CollectModelItems(child, collection);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#endregion
|
||||
}
|
||||
}
|
||||
@ -3654,11 +3654,11 @@ namespace NavisworksTransport.UI.WPF.ViewModels
|
||||
}
|
||||
|
||||
// 调用可见性管理器的公共工具函数
|
||||
var result = VisibilityManager.IsolateSpecificItems(SelectedPreviewResult.Items);
|
||||
bool success = VisibilityHelper.IsolateSpecificItems(SelectedPreviewResult.Items);
|
||||
|
||||
LogManager.Info($"[LayerManagementViewModel] 单独显示执行结果: {result.Success}, {result.Message}");
|
||||
isolateResult = result.Success;
|
||||
resultMessage = result.Message;
|
||||
LogManager.Info($"[LayerManagementViewModel] 单独显示执行结果: {success}");
|
||||
isolateResult = success;
|
||||
resultMessage = success ? "已隔离显示项目" : "隔离显示失败";
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
@ -3732,11 +3732,11 @@ namespace NavisworksTransport.UI.WPF.ViewModels
|
||||
try
|
||||
{
|
||||
// 调用可见性管理器的公共工具函数
|
||||
var result = VisibilityManager.ShowAllItems();
|
||||
bool success = VisibilityHelper.ShowAllItems();
|
||||
|
||||
LogManager.Info($"[LayerManagementViewModel] 恢复显示执行结果: {result.Success}, {result.Message}");
|
||||
restoreResult = result.Success;
|
||||
resultMessage = result.Message;
|
||||
LogManager.Info($"[LayerManagementViewModel] 恢复显示执行结果: {success}");
|
||||
restoreResult = success;
|
||||
resultMessage = success ? "所有项目已显示" : "显示失败";
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
|
||||
@ -539,9 +539,9 @@ namespace NavisworksTransport.UI.WPF.ViewModels
|
||||
/// </summary>
|
||||
private void ShowAllInternal()
|
||||
{
|
||||
var result = VisibilityManager.ShowAllItems();
|
||||
bool success = VisibilityHelper.ShowAllItems();
|
||||
|
||||
if (result.Success)
|
||||
if (success)
|
||||
{
|
||||
// 更新物流模型列表中的可见性状态
|
||||
foreach (var model in LogisticsModels)
|
||||
@ -554,8 +554,8 @@ namespace NavisworksTransport.UI.WPF.ViewModels
|
||||
}
|
||||
else
|
||||
{
|
||||
StatusText = $"显示全部失败: {result.Message}";
|
||||
LogManager.Error($"显示全部失败: {result.Message}");
|
||||
StatusText = "显示全部失败";
|
||||
LogManager.Error("显示全部失败");
|
||||
}
|
||||
}
|
||||
|
||||
@ -567,82 +567,35 @@ namespace NavisworksTransport.UI.WPF.ViewModels
|
||||
var document = NavisApplication.ActiveDocument;
|
||||
if (document?.Models != null)
|
||||
{
|
||||
// 先重置所有隐藏状态
|
||||
document.Models.ResetAllHidden();
|
||||
// 查找所有具有物流属性的元素
|
||||
var logisticsItems = FindAllLogisticsModels();
|
||||
|
||||
// 获取所有具有物流属性的元素
|
||||
var logisticsItems = new HashSet<ModelItem>();
|
||||
var allItems = GetAllModelItems();
|
||||
|
||||
foreach (var item in allItems)
|
||||
if (logisticsItems.Count > 0)
|
||||
{
|
||||
if (CategoryAttributeManager.HasLogisticsAttributes(item))
|
||||
{
|
||||
logisticsItems.Add(item);
|
||||
}
|
||||
}
|
||||
|
||||
// 获取所有需要保持可见的元素
|
||||
var itemsToKeepVisible = new HashSet<ModelItem>();
|
||||
foreach (var logisticsItem in logisticsItems)
|
||||
{
|
||||
// 添加物流元素本身
|
||||
itemsToKeepVisible.Add(logisticsItem);
|
||||
// 使用 VisibilityHelper 来隔离显示物流元素
|
||||
bool success = VisibilityHelper.IsolateSpecificItems(logisticsItems);
|
||||
|
||||
// 添加所有父元素路径(向上)
|
||||
var parent = logisticsItem.Parent;
|
||||
while (parent != null)
|
||||
if (success)
|
||||
{
|
||||
itemsToKeepVisible.Add(parent);
|
||||
parent = parent.Parent;
|
||||
// 更新物流模型列表中的可见性状态
|
||||
foreach (var model in LogisticsModels)
|
||||
{
|
||||
model.IsVisible = true;
|
||||
}
|
||||
|
||||
StatusText = $"仅显示物流元素 ({logisticsItems.Count} 个物流节点)";
|
||||
LogManager.Info($"切换到仅显示物流模式: 找到 {logisticsItems.Count} 个物流节点");
|
||||
}
|
||||
|
||||
// 添加所有子元素(向下)- 物流属性继承给子元素
|
||||
AddAllChildren(logisticsItem, itemsToKeepVisible);
|
||||
}
|
||||
|
||||
// 找出需要隐藏的元素(不在保持可见列表中的元素)
|
||||
var itemsToHide = new List<ModelItem>();
|
||||
foreach (var item in allItems)
|
||||
{
|
||||
if (!itemsToKeepVisible.Contains(item))
|
||||
else
|
||||
{
|
||||
itemsToHide.Add(item);
|
||||
StatusText = "隔离显示物流元素失败";
|
||||
LogManager.Error("隔离显示物流元素失败");
|
||||
}
|
||||
}
|
||||
|
||||
// 执行隐藏操作
|
||||
if (itemsToHide.Count > 0)
|
||||
else
|
||||
{
|
||||
var collectionToHide = new ModelItemCollection();
|
||||
collectionToHide.AddRange(itemsToHide);
|
||||
document.Models.SetHidden(collectionToHide, true);
|
||||
}
|
||||
|
||||
// 更新物流模型列表中的可见性状态
|
||||
foreach (var model in LogisticsModels)
|
||||
{
|
||||
model.IsVisible = true;
|
||||
}
|
||||
|
||||
var totalVisibleItems = itemsToKeepVisible.Count;
|
||||
StatusText = $"仅显示物流元素 ({logisticsItems.Count} 个物流节点,{totalVisibleItems} 个可见元素)";
|
||||
LogManager.Info($"切换到仅显示物流模式: 找到 {logisticsItems.Count} 个物流节点,{totalVisibleItems} 个可见元素");
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 递归添加所有子元素到可见列表
|
||||
/// </summary>
|
||||
private void AddAllChildren(ModelItem parent, HashSet<ModelItem> visibleItems)
|
||||
{
|
||||
if (parent.Children != null)
|
||||
{
|
||||
foreach (ModelItem child in parent.Children)
|
||||
{
|
||||
visibleItems.Add(child);
|
||||
// 递归添加子元素的子元素
|
||||
AddAllChildren(child, visibleItems);
|
||||
StatusText = "未找到物流元素";
|
||||
LogManager.Info("未找到任何物流元素");
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -868,22 +821,6 @@ namespace NavisworksTransport.UI.WPF.ViewModels
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// 异步设置物流属性命令(使用UIStateManager和Command Pattern)
|
||||
/// </summary>
|
||||
|
||||
@ -896,9 +896,9 @@ namespace NavisworksTransport.UI.WPF.ViewModels
|
||||
/// </summary>
|
||||
private void ShowAllInternal()
|
||||
{
|
||||
var result = VisibilityManager.ShowAllItems();
|
||||
bool success = VisibilityHelper.ShowAllItems();
|
||||
|
||||
if (result.Success)
|
||||
if (success)
|
||||
{
|
||||
foreach (var model in LogisticsModels)
|
||||
{
|
||||
@ -910,8 +910,8 @@ namespace NavisworksTransport.UI.WPF.ViewModels
|
||||
}
|
||||
else
|
||||
{
|
||||
UpdateMainStatus($"显示全部失败: {result.Message}");
|
||||
LogManager.Error($"显示全部失败: {result.Message}");
|
||||
UpdateMainStatus("显示全部失败");
|
||||
LogManager.Error("显示全部失败");
|
||||
}
|
||||
}
|
||||
|
||||
@ -945,9 +945,9 @@ namespace NavisworksTransport.UI.WPF.ViewModels
|
||||
LogManager.Info($"[UI-ModelSettings] 使用 Search API 找到 {logisticsItems.Count} 个物流元素");
|
||||
|
||||
// 使用 VisibilityManager 的优化隔离显示方法(带缓存,4-148ms)
|
||||
var result = VisibilityManager.IsolateSpecificItems(logisticsItems);
|
||||
bool success = VisibilityHelper.IsolateSpecificItems(logisticsItems);
|
||||
|
||||
if (result.Success)
|
||||
if (success)
|
||||
{
|
||||
// 更新物流模型列表中的可见性状态
|
||||
foreach (var model in LogisticsModels)
|
||||
@ -955,13 +955,13 @@ namespace NavisworksTransport.UI.WPF.ViewModels
|
||||
model.IsVisible = true;
|
||||
}
|
||||
|
||||
LogManager.Info($"[UI-ModelSettings] 成功隔离显示物流元素:显示 {logisticsItems.Count} 个核心项,隐藏 {result.HiddenCount} 个非物流项");
|
||||
UpdateMainStatus($"仅显示物流元素 ({logisticsItems.Count} 个物流节点,{result.TotalCount - result.HiddenCount} 个可见元素)");
|
||||
LogManager.Info($"[UI-ModelSettings] 成功隔离显示物流元素:显示 {logisticsItems.Count} 个核心项");
|
||||
UpdateMainStatus($"仅显示物流元素 ({logisticsItems.Count} 个物流节点)");
|
||||
}
|
||||
else
|
||||
{
|
||||
LogManager.Error($"[UI-ModelSettings] 隔离显示失败:{result.Message}");
|
||||
UpdateMainStatus($"操作失败:{result.Message}");
|
||||
LogManager.Error("[UI-ModelSettings] 隔离显示失败");
|
||||
UpdateMainStatus("操作失败");
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
@ -971,16 +971,6 @@ namespace NavisworksTransport.UI.WPF.ViewModels
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 递归添加所有子元素到可见列表
|
||||
/// </summary>
|
||||
// 注意:此方法已被VisibilityManager.AddAllChildren公共方法取代,保留仅为兼容性
|
||||
// 建议使用 VisibilityManager.BuildProtectionSet 或 VisibilityManager.AddAllChildren
|
||||
private void AddAllChildren(ModelItem parent, HashSet<ModelItem> visibleItems)
|
||||
{
|
||||
VisibilityManager.AddAllChildren(parent, visibleItems);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 查找所有具有物流属性的模型项
|
||||
/// </summary>
|
||||
|
||||
106
src/Utils/VisibilityHelper.cs
Normal file
106
src/Utils/VisibilityHelper.cs
Normal file
@ -0,0 +1,106 @@
|
||||
using System;
|
||||
using System.Linq;
|
||||
using Autodesk.Navisworks.Api;
|
||||
using NavisApplication = Autodesk.Navisworks.Api.Application;
|
||||
|
||||
namespace NavisworksTransport
|
||||
{
|
||||
/// <summary>
|
||||
/// 可见性管理器
|
||||
/// 负责ModelItem可见性控制的核心业务逻辑
|
||||
/// </summary>
|
||||
public static class VisibilityHelper
|
||||
{
|
||||
|
||||
/// <summary>
|
||||
/// 显示所有项目
|
||||
/// </summary>
|
||||
/// <returns>操作是否成功</returns>
|
||||
public static bool ShowAllItems()
|
||||
{
|
||||
try
|
||||
{
|
||||
NavisApplication.ActiveDocument?.Models?.ResetAllHidden();
|
||||
return true;
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
LogManager.Error($"[VisibilityManager] 显示所有项目失败: {ex.Message}");
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 仅显示指定的模型项集合,隐藏其他所有项
|
||||
/// </summary>
|
||||
/// <param name="itemsToShow">要显示的模型项集合</param>
|
||||
/// <returns>操作是否成功</returns>
|
||||
public static bool IsolateSpecificItems(ModelItemCollection itemsToShow)
|
||||
{
|
||||
try
|
||||
{
|
||||
var stopwatch = System.Diagnostics.Stopwatch.StartNew();
|
||||
|
||||
var document = NavisApplication.ActiveDocument;
|
||||
if (document == null || document.Models.Count == 0)
|
||||
{
|
||||
LogManager.Warning("[VisibilityManager] 没有加载的模型");
|
||||
return false;
|
||||
}
|
||||
|
||||
if (itemsToShow == null || !itemsToShow.Any())
|
||||
{
|
||||
LogManager.Warning("[VisibilityManager] 没有指定要显示的项目");
|
||||
return false;
|
||||
}
|
||||
|
||||
// 1. 重置所有隐藏状态
|
||||
document.Models.ResetAllHidden();
|
||||
|
||||
// 2. 创建可见项集合(要保证从根节点开始的路径完整)
|
||||
ModelItemCollection visible = new ModelItemCollection();
|
||||
|
||||
foreach (ModelItem item in itemsToShow)
|
||||
{
|
||||
// 添加祖先路径
|
||||
if (item.AncestorsAndSelf != null)
|
||||
visible.AddRange(item.AncestorsAndSelf);
|
||||
}
|
||||
|
||||
// 3. 创建候选隐藏集合 - 收集所有可见项的兄弟节点
|
||||
ModelItemCollection hidden = new ModelItemCollection();
|
||||
|
||||
foreach (ModelItem toShow in visible)
|
||||
{
|
||||
if (toShow.Parent != null)
|
||||
{
|
||||
// 添加父节点的所有子节点
|
||||
hidden.AddRange(toShow.Parent.Children);
|
||||
}
|
||||
}
|
||||
|
||||
// 4. 从隐藏集合中移除可见项
|
||||
foreach (ModelItem toShow in visible)
|
||||
{
|
||||
hidden.Remove(toShow);
|
||||
}
|
||||
|
||||
// 5. 执行隐藏操作
|
||||
if (hidden.Count > 0)
|
||||
{
|
||||
document.Models.SetHidden(hidden, true);
|
||||
}
|
||||
|
||||
stopwatch.Stop();
|
||||
LogManager.Info($"[VisibilityManager] 隔离显示完成,耗时 {stopwatch.ElapsedMilliseconds}ms");
|
||||
|
||||
return true;
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
LogManager.Error($"[VisibilityManager] 隔离显示失败: {ex.Message}");
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
Loading…
Reference in New Issue
Block a user