NavisworksTransport/src/TimeLinerIntegrationManager.cs

426 lines
13 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.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
}