using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Linq;
using Autodesk.Navisworks.Api;
using NavisApplication = Autodesk.Navisworks.Api.Application;
namespace NavisworksTransport
{
///
/// 可见性操作结果
///
public class VisibilityOperationResult
{
///
/// 操作是否成功
///
public bool Success { get; set; }
///
/// 结果消息
///
public string Message { get; set; }
///
/// 隐藏的项目数量
///
public int HiddenCount { get; set; }
///
/// 模型总项目数量
///
public int TotalCount { get; set; }
///
/// 错误信息列表
///
public List Errors { get; set; } = new List();
}
///
/// 可见性统计信息
///
public class VisibilityStatistics
{
///
/// 模型总项目数量
///
public int TotalModelItems { get; set; }
///
/// 具有物流分类的项目数量
///
public int LogisticsItems { get; set; }
///
/// 没有物流分类的项目数量
///
public int NonLogisticsItems { get; set; }
///
/// 当前隐藏的项目数量
///
public int HiddenItems { get; set; }
///
/// 当前可见的项目数量
///
public int VisibleItems { get; set; }
}
///
/// 可见性管理器
/// 负责ModelItem可见性控制的核心业务逻辑
///
public class VisibilityManager
{
#region 私有字段
private readonly Document _document;
private List _lastHiddenItems; // 缓存最后一次隐藏的项目列表
#endregion
#region 事件
///
/// 进度报告事件
///
public event EventHandler ProgressChanged;
///
/// 操作完成事件
///
public event EventHandler OperationCompleted;
#endregion
#region 构造函数
///
/// 初始化可见性管理器
///
public VisibilityManager()
{
_document = NavisApplication.ActiveDocument;
_lastHiddenItems = new List();
}
#endregion
#region 静态方法
///
/// 检查ModelItem或其任何子项是否包含物流属性
///
/// 要检查的ModelItem
/// 如果本身或任何子项包含物流属性则返回true
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;
}
///
/// 静态方法:隐藏非物流分类项目
///
/// 操作结果
public static VisibilityOperationResult HideNonLogisticsItems()
{
try
{
var document = NavisApplication.ActiveDocument;
var allItems = GetAllModelItemsStatic();
var itemsToHide = new List();
foreach (var item in allItems)
{
// 只有当项目本身和所有子项都没有物流属性时才隐藏
if (!HasLogisticsAttributesRecursive(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);
}
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 }
};
}
}
///
/// 静态方法:显示所有项目
///
/// 操作结果
public static VisibilityOperationResult ShowAllItems()
{
try
{
var document = NavisApplication.ActiveDocument;
document.Models.ResetAllHidden();
var totalCount = GetAllModelItemsStatic().Count;
return new VisibilityOperationResult
{
Success = true,
Message = "所有项目已显示",
HiddenCount = 0,
TotalCount = totalCount
};
}
catch (Exception ex)
{
return new VisibilityOperationResult
{
Success = false,
Message = $"显示操作失败: {ex.Message}",
HiddenCount = 0,
TotalCount = 0,
Errors = { ex.Message }
};
}
}
///
/// 静态方法:根据物流类型显示特定项目
///
/// 要显示的物流元素类型
/// 操作结果
public static VisibilityOperationResult ShowLogisticsItemsOnly(CategoryAttributeManager.LogisticsElementType elementType)
{
try
{
var document = NavisApplication.ActiveDocument;
var allItems = GetAllModelItemsStatic();
var itemsToHide = new List();
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 }
};
}
}
///
/// 静态方法:获取模型中的所有ModelItem
///
/// ModelItem列表
private static List GetAllModelItemsStatic()
{
var allItems = new List();
try
{
var document = NavisApplication.ActiveDocument;
// 遍历所有根级ModelItem
foreach (ModelItem rootItem in document.Models.RootItems)
{
CollectModelItemsStatic(rootItem, allItems);
}
}
catch (Exception)
{
// 如果遍历失败,返回空列表
return new List();
}
return allItems;
}
///
/// 静态方法:递归收集ModelItem及其所有子项
///
/// 当前ModelItem
/// 收集列表
private static void CollectModelItemsStatic(ModelItem item, List collection)
{
if (item == null) return;
// 添加当前项目
collection.Add(item);
// 递归添加子项目
if (item.Children != null && item.Children.Count() > 0)
{
foreach (ModelItem child in item.Children)
{
CollectModelItemsStatic(child, collection);
}
}
}
#endregion
#region 实例方法
///
/// 异步隐藏非物流分类项目
///
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();
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();
}
///
/// 实例方法:同步隐藏非物流分类项目(用于小型模型)
///
/// 操作结果
public VisibilityOperationResult HideNonLogisticsItemsInstance()
{
try
{
var allItems = GetAllModelItems();
var itemsToHide = new List();
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 }
};
}
}
///
/// 实例方法:显示所有项目
///
/// 操作结果
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 }
};
}
}
///
/// 获取当前可见性统计信息
///
/// 可见性统计信息
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 私有方法
///
/// 获取模型中的所有ModelItem
///
/// ModelItem列表
private List GetAllModelItems()
{
var allItems = new List();
try
{
// 遍历所有根级ModelItem
foreach (ModelItem rootItem in _document.Models.RootItems)
{
CollectModelItems(rootItem, allItems);
}
}
catch (Exception)
{
// 如果遍历失败,返回空列表
return new List();
}
return allItems;
}
///
/// 递归收集ModelItem及其所有子项
///
/// 当前ModelItem
/// 收集列表
private void CollectModelItems(ModelItem item, List 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
}
}