NavisworksTransport/VisibilityManager.cs

605 lines
19 KiB
C#
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

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
}
}