NavisworksTransport/src/Utils/NavisworksApiHelper.cs

169 lines
6.0 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 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;
}
}
}
}