169 lines
6.0 KiB
C#
169 lines
6.0 KiB
C#
using System;
|
||
using Autodesk.Navisworks.Api;
|
||
|
||
namespace NavisworksTransport.Utils
|
||
{
|
||
/// <summary>
|
||
/// Navisworks API 通用工具类
|
||
/// 提供跨模块使用的通用 API 操作方法
|
||
/// </summary>
|
||
public static class NavisworksApiHelper
|
||
{
|
||
/// <summary>
|
||
/// 安全的缓存刷新方法
|
||
/// 用于解决某些 API 操作后缓存不同步的问题
|
||
/// 基于实际生产环境的验证,使用空集合的 SetHidden 操作来触发缓存更新
|
||
/// </summary>
|
||
/// <param name="logPrefix">日志前缀,用于标识调用方</param>
|
||
public static void SafeCacheRefresh(string logPrefix = "NavisworksApiHelper")
|
||
{
|
||
try
|
||
{
|
||
var document = Application.ActiveDocument;
|
||
if (document?.Models != null)
|
||
{
|
||
// 使用更安全的空操作来触发缓存更新
|
||
// 方法: 空集合的SetHidden操作(几乎零开销的伪操作)
|
||
var emptyCollection = new ModelItemCollection();
|
||
document.Models.SetHidden(emptyCollection, false);
|
||
LogManager.Debug($"[{logPrefix}] ✅ 已执行轻量级缓存刷新");
|
||
}
|
||
}
|
||
catch (Exception refreshEx)
|
||
{
|
||
LogManager.Warning($"[{logPrefix}] ⚠️ 缓存刷新失败,但不影响主要操作: {refreshEx.Message}");
|
||
}
|
||
}
|
||
|
||
/// <summary>
|
||
/// 线程安全的缓存刷新方法
|
||
/// 确保缓存刷新操作在主 UI 线程中执行
|
||
/// </summary>
|
||
/// <param name="logPrefix">日志前缀,用于标识调用方</param>
|
||
public static void SafeCacheRefreshUIThread(string logPrefix = "NavisworksApiHelper")
|
||
{
|
||
if (System.Windows.Application.Current?.Dispatcher?.CheckAccess() == true)
|
||
{
|
||
SafeCacheRefresh(logPrefix);
|
||
}
|
||
else
|
||
{
|
||
System.Windows.Application.Current.Dispatcher.Invoke(() =>
|
||
{
|
||
SafeCacheRefresh(logPrefix);
|
||
});
|
||
}
|
||
}
|
||
|
||
/// <summary>
|
||
/// 检查当前是否在主 UI 线程中
|
||
/// </summary>
|
||
/// <returns>在主 UI 线程中返回 true</returns>
|
||
public static bool IsOnUIThread()
|
||
{
|
||
return System.Windows.Application.Current?.Dispatcher?.CheckAccess() == true;
|
||
}
|
||
|
||
/// <summary>
|
||
/// 在主 UI 线程中执行操作,确保线程安全
|
||
/// </summary>
|
||
/// <typeparam name="T">返回值类型</typeparam>
|
||
/// <param name="operation">要执行的操作</param>
|
||
/// <returns>操作结果</returns>
|
||
public static T ExecuteOnUIThread<T>(Func<T> operation)
|
||
{
|
||
if (IsOnUIThread())
|
||
{
|
||
return operation();
|
||
}
|
||
else
|
||
{
|
||
return System.Windows.Application.Current.Dispatcher.Invoke(operation);
|
||
}
|
||
}
|
||
|
||
/// <summary>
|
||
/// 在主 UI 线程中执行操作,确保线程安全(无返回值)
|
||
/// </summary>
|
||
/// <param name="operation">要执行的操作</param>
|
||
public static void ExecuteOnUIThread(Action operation)
|
||
{
|
||
if (IsOnUIThread())
|
||
{
|
||
operation();
|
||
}
|
||
else
|
||
{
|
||
System.Windows.Application.Current.Dispatcher.Invoke(operation);
|
||
}
|
||
}
|
||
|
||
/// <summary>
|
||
/// 获取ModelItem的直接显示名称(不溯源父节点)
|
||
/// 仅从当前节点获取名称,适用于不需要父节点信息的场景
|
||
/// </summary>
|
||
/// <param name="item">要获取名称的ModelItem</param>
|
||
/// <returns>元素的显示名称</returns>
|
||
public static string GetModelItemName(ModelItem item)
|
||
{
|
||
if (item == null) return "未知对象";
|
||
|
||
try
|
||
{
|
||
// 1. 尝试DisplayName
|
||
if (!string.IsNullOrEmpty(item.DisplayName))
|
||
{
|
||
return item.DisplayName;
|
||
}
|
||
|
||
// 2. 尝试ClassDisplayName
|
||
if (!string.IsNullOrEmpty(item.ClassDisplayName))
|
||
{
|
||
return item.ClassDisplayName;
|
||
}
|
||
|
||
return "未命名对象";
|
||
}
|
||
catch (Exception ex)
|
||
{
|
||
LogManager.Error($"获取ModelItem名称失败: {ex.Message}");
|
||
return "获取失败";
|
||
}
|
||
}
|
||
|
||
|
||
|
||
/// <summary>
|
||
/// 使用 ModelItemPathId 查找 ModelItem(推荐方式)
|
||
/// </summary>
|
||
/// <param name="modelIndex">模型索引</param>
|
||
/// <param name="pathId">路径标识符</param>
|
||
/// <returns>找到的ModelItem,如果找不到返回null</returns>
|
||
public static ModelItem FindModelItemByPathId(int modelIndex, string pathId)
|
||
{
|
||
try
|
||
{
|
||
var pathIdObj = new Autodesk.Navisworks.Api.DocumentParts.ModelItemPathId();
|
||
pathIdObj.ModelIndex = modelIndex;
|
||
pathIdObj.PathId = pathId;
|
||
var modelItem = Application.ActiveDocument.Models.ResolvePathId(pathIdObj);
|
||
|
||
if (modelItem != null)
|
||
{
|
||
LogManager.Debug($"[FindModelItemByPathId] 成功找到ModelItem: ModelIndex={modelIndex}, PathId={pathId}");
|
||
}
|
||
else
|
||
{
|
||
LogManager.Warning($"[FindModelItemByPathId] 未找到ModelItem: ModelIndex={modelIndex}, PathId={pathId}");
|
||
}
|
||
|
||
return modelItem;
|
||
}
|
||
catch (Exception ex)
|
||
{
|
||
LogManager.Error($"[FindModelItemByPathId] 查找失败: {ex.Message}", ex);
|
||
return null;
|
||
}
|
||
}
|
||
}
|
||
} |