426 lines
13 KiB
C#
426 lines
13 KiB
C#
using System;
|
||
using System.Collections.Generic;
|
||
using System.Linq;
|
||
using System.Reflection;
|
||
using Autodesk.Navisworks.Api;
|
||
using Autodesk.Navisworks.Api.Timeliner;
|
||
using Autodesk.Navisworks.Api.DocumentParts;
|
||
|
||
namespace NavisworksTransport
|
||
{
|
||
/// <summary>
|
||
/// TimeLiner 集成管理器
|
||
/// 实现运输任务与 Navisworks TimeLiner 的集成
|
||
/// </summary>
|
||
public class TimeLinerIntegrationManager
|
||
{
|
||
#region 私有字段
|
||
|
||
private DocumentTimeliner _documentTimeliner;
|
||
private readonly Dictionary<string, TimelinerTask> _transportTasks;
|
||
private readonly Dictionary<string, PathAnimationManager> _animationManagers;
|
||
private bool _isTimeLinerAvailable;
|
||
|
||
#endregion
|
||
|
||
#region 事件
|
||
|
||
/// <summary>
|
||
/// TimeLiner 状态变化事件
|
||
/// </summary>
|
||
public event EventHandler<TimeLinerStatusEventArgs> StatusChanged;
|
||
|
||
/// <summary>
|
||
/// 任务创建事件
|
||
/// </summary>
|
||
public event EventHandler<TaskCreatedEventArgs> TaskCreated;
|
||
|
||
#endregion
|
||
|
||
#region 构造函数
|
||
|
||
public TimeLinerIntegrationManager()
|
||
{
|
||
_transportTasks = new Dictionary<string, TimelinerTask>();
|
||
_animationManagers = new Dictionary<string, PathAnimationManager>();
|
||
|
||
InitializeTimeLiner();
|
||
}
|
||
|
||
#endregion
|
||
|
||
#region 公共属性
|
||
|
||
/// <summary>
|
||
/// TimeLiner 是否可用
|
||
/// </summary>
|
||
public bool IsTimeLinerAvailable => _isTimeLinerAvailable;
|
||
|
||
/// <summary>
|
||
/// 当前运输任务数量
|
||
/// </summary>
|
||
public int TaskCount => _transportTasks.Count;
|
||
|
||
#endregion
|
||
|
||
#region 私有方法
|
||
|
||
/// <summary>
|
||
/// 初始化 TimeLiner
|
||
/// </summary>
|
||
private void InitializeTimeLiner()
|
||
{
|
||
try
|
||
{
|
||
var activeDocument = Application.ActiveDocument;
|
||
if (activeDocument == null)
|
||
{
|
||
LogManager.Warning("没有活动文档,TimeLiner 初始化失败");
|
||
_isTimeLinerAvailable = false;
|
||
return;
|
||
}
|
||
|
||
_documentTimeliner = activeDocument.GetTimeliner();
|
||
_isTimeLinerAvailable = _documentTimeliner != null;
|
||
|
||
if (_isTimeLinerAvailable)
|
||
{
|
||
LogManager.Info("✓ TimeLiner 集成管理器初始化成功");
|
||
OnStatusChanged("TimeLiner 已连接");
|
||
}
|
||
else
|
||
{
|
||
LogManager.Warning("✗ TimeLiner 不可用,将使用降级模式");
|
||
OnStatusChanged("TimeLiner 不可用");
|
||
}
|
||
}
|
||
catch (Exception ex)
|
||
{
|
||
LogManager.Error($"TimeLiner 初始化失败: {ex.Message}");
|
||
_isTimeLinerAvailable = false;
|
||
OnStatusChanged("TimeLiner 初始化失败");
|
||
}
|
||
}
|
||
|
||
/// <summary>
|
||
/// 生成唯一的任务ID
|
||
/// </summary>
|
||
private string GenerateTaskId()
|
||
{
|
||
return $"TransportTask_{DateTime.Now:yyyyMMdd_HHmmss}_{Guid.NewGuid().ToString("N").Substring(0, 6)}";
|
||
}
|
||
|
||
/// <summary>
|
||
/// 触发状态变化事件
|
||
/// </summary>
|
||
private void OnStatusChanged(string status)
|
||
{
|
||
StatusChanged?.Invoke(this, new TimeLinerStatusEventArgs(status));
|
||
}
|
||
|
||
/// <summary>
|
||
/// 触发任务创建事件
|
||
/// </summary>
|
||
private void OnTaskCreated(string taskId, TimelinerTask task)
|
||
{
|
||
TaskCreated?.Invoke(this, new TaskCreatedEventArgs(taskId, task));
|
||
}
|
||
|
||
#endregion
|
||
|
||
#region 公共方法
|
||
|
||
/// <summary>
|
||
/// 创建运输任务
|
||
/// </summary>
|
||
/// <param name="taskName">任务名称</param>
|
||
/// <param name="pathPoints">路径点集合</param>
|
||
/// <param name="duration">动画持续时间</param>
|
||
/// <param name="vehicle">运输车辆</param>
|
||
/// <returns>任务ID,如果创建失败返回null</returns>
|
||
public string CreateTransportTask(string taskName, List<Point3D> pathPoints, TimeSpan duration, ModelItem vehicle)
|
||
{
|
||
try
|
||
{
|
||
if (!_isTimeLinerAvailable)
|
||
{
|
||
LogManager.Warning("TimeLiner 不可用,无法创建任务");
|
||
return null;
|
||
}
|
||
|
||
if (pathPoints == null || pathPoints.Count < 2)
|
||
{
|
||
LogManager.Warning("路径点不足,无法创建运输任务");
|
||
return null;
|
||
}
|
||
|
||
if (vehicle == null)
|
||
{
|
||
LogManager.Warning("未指定运输车辆,无法创建任务");
|
||
return null;
|
||
}
|
||
|
||
var taskId = GenerateTaskId();
|
||
var task = new TimelinerTask();
|
||
|
||
// 设置任务基本信息
|
||
task.DisplayName = $"运输任务:{taskName}";
|
||
LogManager.Info($"设置任务显示名称: {task.DisplayName}");
|
||
|
||
// 关联运输车辆
|
||
var modelItems = new ModelItemCollection();
|
||
modelItems.Add(vehicle);
|
||
task.Selection.CopyFrom(modelItems);
|
||
|
||
// 将任务添加到 TimeLiner - 使用正确的API方法
|
||
if (_documentTimeliner?.Tasks != null)
|
||
{
|
||
// 使用TaskAddCopy方法添加任务副本
|
||
try
|
||
{
|
||
_documentTimeliner.TaskAddCopy(task);
|
||
LogManager.Info($"✓ TimeLiner 任务添加成功,当前任务数量: {_documentTimeliner.Tasks.Count}");
|
||
}
|
||
catch (Exception ex)
|
||
{
|
||
LogManager.Error($"TimeLiner 任务添加失败: {ex.Message}");
|
||
return null;
|
||
}
|
||
}
|
||
else
|
||
{
|
||
LogManager.Error("TimeLiner Tasks 集合不可用");
|
||
return null;
|
||
}
|
||
|
||
// 保存任务引用
|
||
_transportTasks[taskId] = task;
|
||
|
||
LogManager.Info($"✓ 运输任务创建成功: {taskName} (ID: {taskId})");
|
||
OnTaskCreated(taskId, task);
|
||
OnStatusChanged($"已创建任务: {taskName}");
|
||
|
||
return taskId;
|
||
}
|
||
catch (Exception ex)
|
||
{
|
||
LogManager.Error($"创建运输任务失败: {ex.Message}");
|
||
return null;
|
||
}
|
||
}
|
||
|
||
/// <summary>
|
||
/// 更新任务进度
|
||
/// </summary>
|
||
/// <param name="taskId">任务ID</param>
|
||
/// <param name="progress">进度(0.0 - 1.0)</param>
|
||
/// <param name="animationState">动画状态</param>
|
||
public void UpdateTaskProgress(string taskId, double progress, AnimationState animationState)
|
||
{
|
||
try
|
||
{
|
||
if (!_transportTasks.ContainsKey(taskId))
|
||
{
|
||
LogManager.Warning($"未找到任务ID: {taskId}");
|
||
return;
|
||
}
|
||
|
||
var task = _transportTasks[taskId];
|
||
|
||
// 由于Navisworks 2017的TimelinerTask可能没有UserData属性
|
||
// 使用任务名称来传递状态信息
|
||
string statusText;
|
||
switch (animationState)
|
||
{
|
||
case AnimationState.Playing:
|
||
statusText = "播放中";
|
||
break;
|
||
case AnimationState.Paused:
|
||
statusText = "暂停";
|
||
break;
|
||
case AnimationState.Stopped:
|
||
statusText = "已停止";
|
||
break;
|
||
case AnimationState.Finished:
|
||
statusText = "已完成";
|
||
break;
|
||
default:
|
||
statusText = "未知状态";
|
||
break;
|
||
}
|
||
|
||
// 更新任务显示名称以反映当前状态
|
||
var baseName = task.DisplayName.Split('[')[0].Trim();
|
||
task.DisplayName = $"{baseName} [{statusText} {progress:P1}] - {DateTime.Now:HH:mm:ss}";
|
||
|
||
LogManager.Debug($"任务进度更新: {taskId}, 进度: {progress:P1}, 状态: {statusText}");
|
||
}
|
||
catch (Exception ex)
|
||
{
|
||
LogManager.Error($"更新任务进度失败: {ex.Message}");
|
||
}
|
||
}
|
||
|
||
/// <summary>
|
||
/// 删除运输任务
|
||
/// </summary>
|
||
/// <param name="taskId">任务ID</param>
|
||
public bool RemoveTransportTask(string taskId)
|
||
{
|
||
try
|
||
{
|
||
if (!_transportTasks.ContainsKey(taskId))
|
||
{
|
||
LogManager.Warning($"未找到要删除的任务ID: {taskId}");
|
||
return false;
|
||
}
|
||
|
||
var task = _transportTasks[taskId];
|
||
|
||
// 从 TimeLiner 中移除任务
|
||
if (_documentTimeliner?.Tasks != null && _documentTimeliner.Tasks.Contains(task))
|
||
{
|
||
_documentTimeliner.Tasks.Remove(task);
|
||
}
|
||
|
||
// 清理本地引用
|
||
_transportTasks.Remove(taskId);
|
||
|
||
if (_animationManagers.ContainsKey(taskId))
|
||
{
|
||
_animationManagers.Remove(taskId);
|
||
}
|
||
|
||
LogManager.Info($"运输任务已删除: {taskId}");
|
||
OnStatusChanged($"已删除任务: {task.DisplayName}");
|
||
|
||
return true;
|
||
}
|
||
catch (Exception ex)
|
||
{
|
||
LogManager.Error($"删除运输任务失败: {ex.Message}");
|
||
return false;
|
||
}
|
||
}
|
||
|
||
/// <summary>
|
||
/// 获取所有运输任务
|
||
/// </summary>
|
||
public Dictionary<string, TimelinerTask> GetAllTransportTasks()
|
||
{
|
||
return new Dictionary<string, TimelinerTask>(_transportTasks);
|
||
}
|
||
|
||
/// <summary>
|
||
/// 检查 TimeLiner 可用性
|
||
/// </summary>
|
||
public bool CheckTimeLinerAvailability()
|
||
{
|
||
try
|
||
{
|
||
var activeDocument = Application.ActiveDocument;
|
||
if (activeDocument == null)
|
||
{
|
||
_isTimeLinerAvailable = false;
|
||
return false;
|
||
}
|
||
|
||
var timeLiner = activeDocument.GetTimeliner();
|
||
_isTimeLinerAvailable = timeLiner != null;
|
||
|
||
if (_isTimeLinerAvailable && _documentTimeliner != timeLiner)
|
||
{
|
||
_documentTimeliner = timeLiner;
|
||
LogManager.Info("TimeLiner 引用已更新");
|
||
}
|
||
|
||
return _isTimeLinerAvailable;
|
||
}
|
||
catch (Exception ex)
|
||
{
|
||
LogManager.Error($"检查 TimeLiner 可用性失败: {ex.Message}");
|
||
_isTimeLinerAvailable = false;
|
||
return false;
|
||
}
|
||
}
|
||
|
||
/// <summary>
|
||
/// 清理所有任务
|
||
/// </summary>
|
||
public void ClearAllTasks()
|
||
{
|
||
try
|
||
{
|
||
var taskIds = _transportTasks.Keys.ToList();
|
||
foreach (var taskId in taskIds)
|
||
{
|
||
RemoveTransportTask(taskId);
|
||
}
|
||
|
||
LogManager.Info("所有运输任务已清理");
|
||
OnStatusChanged("所有任务已清理");
|
||
}
|
||
catch (Exception ex)
|
||
{
|
||
LogManager.Error($"清理任务失败: {ex.Message}");
|
||
}
|
||
}
|
||
|
||
/// <summary>
|
||
/// 释放资源
|
||
/// </summary>
|
||
public void Dispose()
|
||
{
|
||
try
|
||
{
|
||
ClearAllTasks();
|
||
_documentTimeliner = null;
|
||
_isTimeLinerAvailable = false;
|
||
|
||
LogManager.Info("TimeLiner 集成管理器已释放");
|
||
}
|
||
catch (Exception ex)
|
||
{
|
||
LogManager.Error($"释放 TimeLiner 集成管理器失败: {ex.Message}");
|
||
}
|
||
}
|
||
|
||
#endregion
|
||
}
|
||
|
||
#region 事件参数类
|
||
|
||
/// <summary>
|
||
/// TimeLiner 状态事件参数
|
||
/// </summary>
|
||
public class TimeLinerStatusEventArgs : EventArgs
|
||
{
|
||
public string Status { get; }
|
||
public DateTime Timestamp { get; }
|
||
|
||
public TimeLinerStatusEventArgs(string status)
|
||
{
|
||
Status = status;
|
||
Timestamp = DateTime.Now;
|
||
}
|
||
}
|
||
|
||
/// <summary>
|
||
/// 任务创建事件参数
|
||
/// </summary>
|
||
public class TaskCreatedEventArgs : EventArgs
|
||
{
|
||
public string TaskId { get; }
|
||
public TimelinerTask Task { get; }
|
||
public DateTime Timestamp { get; }
|
||
|
||
public TaskCreatedEventArgs(string taskId, TimelinerTask task)
|
||
{
|
||
TaskId = taskId;
|
||
Task = task;
|
||
Timestamp = DateTime.Now;
|
||
}
|
||
}
|
||
|
||
#endregion
|
||
} |