605 lines
19 KiB
C#
605 lines
19 KiB
C#
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 document = NavisApplication.ActiveDocument;
|
||
var allItems = GetAllModelItemsStatic();
|
||
var itemsToHide = new List<ModelItem>();
|
||
|
||
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 }
|
||
};
|
||
}
|
||
}
|
||
|
||
/// <summary>
|
||
/// 静态方法:显示所有项目
|
||
/// </summary>
|
||
/// <returns>操作结果</returns>
|
||
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 }
|
||
};
|
||
}
|
||
}
|
||
|
||
/// <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 allItems = new List<ModelItem>();
|
||
|
||
try
|
||
{
|
||
var document = NavisApplication.ActiveDocument;
|
||
// 遍历所有根级ModelItem
|
||
foreach (ModelItem rootItem in document.Models.RootItems)
|
||
{
|
||
CollectModelItemsStatic(rootItem, allItems);
|
||
}
|
||
}
|
||
catch (Exception)
|
||
{
|
||
// 如果遍历失败,返回空列表
|
||
return new List<ModelItem>();
|
||
}
|
||
|
||
return allItems;
|
||
}
|
||
|
||
/// <summary>
|
||
/// 静态方法:递归收集ModelItem及其所有子项
|
||
/// </summary>
|
||
/// <param name="item">当前ModelItem</param>
|
||
/// <param name="collection">收集列表</param>
|
||
private static void CollectModelItemsStatic(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)
|
||
{
|
||
CollectModelItemsStatic(child, collection);
|
||
}
|
||
}
|
||
}
|
||
|
||
#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 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
|
||
}
|
||
} |