清理动画的无效代码

This commit is contained in:
tian 2025-09-14 03:08:12 +08:00
parent 6510a0e124
commit d1185d986d
4 changed files with 87 additions and 242 deletions

View File

@ -361,9 +361,6 @@ namespace NavisworksTransport.Core.Animation
_allCollisionResults = new List<CollisionResult>();
_currentFrameIndex = 0;
// 初始化碰撞检测系统
ClashDetectiveIntegration.Instance.Initialize();
// 获取动画对象的包围盒信息
var originalBoundingBox = _animatedObject.BoundingBox();
var boundingBoxSize = new Vector3D(
@ -466,9 +463,8 @@ namespace NavisworksTransport.Core.Animation
try
{
LogManager.Info("开始获取潜在碰撞对象");
// 确保ClashDetectiveIntegration已初始化并构建了通道缓存
ClashDetectiveIntegration.Instance.Initialize();
// 构建通道缓存
ClashDetectiveIntegration.Instance.BuildChannelObjectsCache();
ClashDetectiveIntegration.BuildAllGeometryItemsCache();
@ -600,11 +596,11 @@ namespace NavisworksTransport.Core.Animation
}
// 创建 TimeLiner 任务(如果可用
// 创建 TimeLiner 任务(如果可用且未创建过
if (_timeLinerManager != null && _timeLinerManager.IsTimeLinerAvailable)
{
string objectName = "UnknownObject";
try
try
{
objectName = _animatedObject?.DisplayName ?? "UnknownObject";
}
@ -612,24 +608,38 @@ namespace NavisworksTransport.Core.Animation
{
objectName = "DisposedObject";
}
var taskName = $"{objectName}_运输_{DateTime.Now:HHmmss}";
var duration = TimeSpan.FromSeconds(_animationDuration);
LogManager.Info($"创建 TimeLiner 任务: {taskName}");
_currentTaskId = _timeLinerManager.CreateTransportTask(
taskName,
_pathPoints,
duration,
_animatedObject);
if (!string.IsNullOrEmpty(_currentTaskId))
// 使用动画配置hash作为任务标识
var hashPrefix = _currentAnimationHash.Substring(0, Math.Min(8, _currentAnimationHash.Length));
var taskName = $"{objectName}_运输_{hashPrefix}";
// 检查是否已存在相同配置的任务
var existingTaskId = _timeLinerManager.FindTaskByName(taskName);
if (!string.IsNullOrEmpty(existingTaskId))
{
LogManager.Info($"✓ TimeLiner 任务创建成功: {taskName} (ID: {_currentTaskId})");
_currentTaskId = existingTaskId;
LogManager.Info($"复用现有 TimeLiner 任务: {taskName} (ID: {_currentTaskId})");
}
else
{
LogManager.Warning("TimeLiner 任务创建失败,继续使用基础动画功能");
// 创建新任务
var duration = TimeSpan.FromSeconds(_animationDuration);
LogManager.Info($"创建 TimeLiner 任务: {taskName}");
_currentTaskId = _timeLinerManager.CreateTransportTask(
taskName,
_pathPoints,
duration,
_animatedObject);
if (!string.IsNullOrEmpty(_currentTaskId))
{
LogManager.Info($"✓ TimeLiner 任务创建成功: {taskName} (ID: {_currentTaskId})");
}
else
{
LogManager.Warning("TimeLiner 任务创建失败,继续使用基础动画功能");
}
}
}
else
@ -1326,9 +1336,6 @@ namespace NavisworksTransport.Core.Animation
{
try
{
// 初始化 Clash Detective 集成
ClashDetectiveIntegration.Instance.Initialize();
// 订阅碰撞检测事件
ClashDetectiveIntegration.Instance.CollisionDetected += OnClashDetectiveCollisionDetected;

View File

@ -309,6 +309,34 @@ namespace NavisworksTransport.Core.Animation
return new Dictionary<string, TimelinerTask>(_transportTasks);
}
/// <summary>
/// 根据任务名称查找现有任务ID
/// </summary>
/// <param name="taskName">要查找的任务名称</param>
/// <returns>找到的任务ID如果不存在则返回null</returns>
public string FindTaskByName(string taskName)
{
try
{
foreach (var kvp in _transportTasks)
{
if (kvp.Value != null && kvp.Value.DisplayName != null && kvp.Value.DisplayName.Contains(taskName))
{
LogManager.Debug($"找到现有任务: {kvp.Value.DisplayName} (ID: {kvp.Key})");
return kvp.Key;
}
}
LogManager.Debug($"未找到名称为 '{taskName}' 的任务");
return null;
}
catch (Exception ex)
{
LogManager.Error($"查找任务失败: {ex.Message}");
return null;
}
}
/// <summary>
/// 检查 TimeLiner 可用性
/// </summary>

View File

@ -77,17 +77,12 @@ namespace NavisworksTransport
{
_currentCollisions = new List<ClashResult>();
_cachedResults = new List<CollisionResult>();
}
/// <summary>
/// 初始化Clash Detective集成 - 纯.NET API模式
/// </summary>
public void Initialize()
{
// 自动初始化 Clash Detective 集成
try
{
LogManager.Info("初始化Clash Detective集成.NET API模式...");
// 直接使用.NET API获取Clash文档
_documentClash = Application.ActiveDocument.GetClash();
if (_documentClash != null)
@ -103,10 +98,10 @@ namespace NavisworksTransport
catch (Exception ex)
{
LogManager.Error($"初始化Clash Detective集成失败: {ex.Message}");
_documentClash = null;
}
}
/// <summary>
/// 创建碰撞快照(动画结束后一次性更新结果)
/// </summary>

View File

@ -7,13 +7,8 @@ using System.Windows.Input;
using System.Windows.Threading;
using Autodesk.Navisworks.Api;
using Autodesk.Navisworks.Api.Clash;
using NavisworksTransport.Commands;
using NavisworksTransport.Core.Animation;
using NavisworksTransport.Core;
using NavisworksTransport.UI.WPF.Commands;
using NavisworksTransport.UI.WPF.Collections;
using NavisworksTransport.UI.WPF.Models;
using NavisworksTransport.Utils;
namespace NavisworksTransport.UI.WPF.ViewModels
{
@ -91,10 +86,6 @@ namespace NavisworksTransport.UI.WPF.ViewModels
private int _animationFrameRate = 30; // 动画帧率(FPS)
private double _collisionDetectionFrequency = 10.0; // 检测频率(次/秒)
// 防抖机制相关字段
private DispatcherTimer _parameterUpdateTimer;
private readonly object _parameterUpdateLock = new object();
private volatile bool _hasParameterChanges = false;
// 当前选中路径
private PathRouteViewModel _currentPathRoute;
@ -184,14 +175,13 @@ namespace NavisworksTransport.UI.WPF.ViewModels
public double CollisionDetectionAccuracy
{
get => _collisionDetectionAccuracy;
set
{
set
{
// 限制精度到2位小数
var roundedValue = Math.Round(value, 2);
if (SetProperty(ref _collisionDetectionAccuracy, roundedValue))
{
UpdateCollisionDetectionFrequency();
ScheduleParameterUpdate();
}
}
}
@ -202,14 +192,13 @@ namespace NavisworksTransport.UI.WPF.ViewModels
public double MovementSpeed
{
get => _movementSpeed;
set
{
set
{
// 限制精度到1位小数
var roundedValue = Math.Round(value, 1);
if (SetProperty(ref _movementSpeed, roundedValue))
{
UpdateCollisionDetectionFrequency();
ScheduleParameterUpdate();
}
}
}
@ -220,14 +209,11 @@ namespace NavisworksTransport.UI.WPF.ViewModels
public double DetectionGap
{
get => _detectionGap;
set
{
set
{
// 限制精度到2位小数
var roundedValue = Math.Round(value, 2);
if (SetProperty(ref _detectionGap, roundedValue))
{
ScheduleParameterUpdate();
}
SetProperty(ref _detectionGap, roundedValue);
}
}
@ -237,12 +223,9 @@ namespace NavisworksTransport.UI.WPF.ViewModels
public int AnimationFrameRate
{
get => _animationFrameRate;
set
{
if (SetProperty(ref _animationFrameRate, value))
{
UpdatePathAnimationManagerSettings();
}
set
{
SetProperty(ref _animationFrameRate, value);
}
}
@ -447,11 +430,8 @@ namespace NavisworksTransport.UI.WPF.ViewModels
// 初始化命令
InitializeCommands();
// 初始化碰撞检测集成
InitializeClashIntegration();
// 初始化防抖定时器
InitializeParameterUpdateTimer();
// 订阅碰撞检测事件
_clashIntegration.CollisionDetected += OnCollisionDetected;
LogManager.Info("AnimationControlViewModel初始化完成含缓存管理");
}
@ -492,12 +472,9 @@ namespace NavisworksTransport.UI.WPF.ViewModels
// 初始化命令
InitializeCommands();
// 初始化碰撞检测集成
InitializeClashIntegration();
// 初始化防抖定时器
InitializeParameterUpdateTimer();
// 订阅碰撞检测事件
_clashIntegration.CollisionDetected += OnCollisionDetected;
// 订阅文档状态事件
DocumentStateManager.Instance.DocumentInvalidated += OnDocumentInvalidated;
DocumentStateManager.Instance.DocumentReady += OnDocumentReady;
@ -547,9 +524,6 @@ namespace NavisworksTransport.UI.WPF.ViewModels
DetectionGap = 0.05; // 0.05米
AnimationFrameRate = 30; // 30FPS
UpdateCollisionDetectionFrequency(); // 计算初始检测频率
// 初始化动画管理器设置
UpdatePathAnimationManagerSettings();
// 修改: 使用新的按钮状态更新方法来设置正确的初始状态
UpdateAnimationButtonStates();
@ -584,22 +558,6 @@ namespace NavisworksTransport.UI.WPF.ViewModels
LogManager.Info("动画控制命令初始化完成");
}
/// <summary>
/// 初始化碰撞检测集成
/// </summary>
private void InitializeClashIntegration()
{
try
{
_clashIntegration.Initialize();
_clashIntegration.CollisionDetected += OnCollisionDetected;
LogManager.Info("碰撞检测集成初始化完成");
}
catch (Exception ex)
{
LogManager.Error($"碰撞检测集成初始化失败: {ex.Message}");
}
}
#endregion
@ -1055,8 +1013,6 @@ namespace NavisworksTransport.UI.WPF.ViewModels
CanPauseAnimation = false;
CanStopAnimation = false;
UpdateMainStatus("动画已完成");
// 动画完成后更新碰撞检测状态
UpdateCollisionStatusAfterAnimation();
UpdateMediaControlProperties(); // 更新媒体控制属性
break;
case NavisworksTransport.Core.Animation.AnimationState.Stopped:
@ -1345,7 +1301,13 @@ namespace NavisworksTransport.UI.WPF.ViewModels
// 原有的动画生成逻辑
UpdateMainStatus("正在生成路径动画...", -1, true);
// 设置动画参数到PathAnimationManager
_pathAnimationManager.SetAnimationFrameRate(_animationFrameRate);
_pathAnimationManager.SetCollisionDetectionAccuracy(_collisionDetectionAccuracy);
_pathAnimationManager.SetMovementSpeed(_movementSpeed);
_pathAnimationManager.SetDetectionGap(_detectionGap);
// 将PathRouteViewModel的点转换为Point3D列表
var pathPoints = CurrentPathRoute.Points.Select(p => new Point3D(p.X, p.Y, p.Z)).ToList();
@ -1530,138 +1492,7 @@ namespace NavisworksTransport.UI.WPF.ViewModels
LogManager.Error($"更新动画按钮状态时发生错误: {ex.Message}", ex);
}
}
/// <summary>
/// 初始化参数更新防抖定时器
/// </summary>
private void InitializeParameterUpdateTimer()
{
_parameterUpdateTimer = new DispatcherTimer
{
Interval = TimeSpan.FromMilliseconds(150) // 150毫秒防抖延迟
};
_parameterUpdateTimer.Tick += OnParameterUpdateTimerTick;
}
/// <summary>
/// 定时器触发时执行参数更新
/// </summary>
private void OnParameterUpdateTimerTick(object sender, EventArgs e)
{
_parameterUpdateTimer.Stop();
lock (_parameterUpdateLock)
{
if (_hasParameterChanges)
{
_hasParameterChanges = false;
UpdatePathAnimationManagerSettings();
}
}
}
/// <summary>
/// 计划参数更新(防抖机制)
/// </summary>
private void ScheduleParameterUpdate()
{
lock (_parameterUpdateLock)
{
_hasParameterChanges = true;
_parameterUpdateTimer.Stop();
_parameterUpdateTimer.Start();
}
}
/// <summary>
/// 更新PathAnimationManager的设置
/// </summary>
private void UpdatePathAnimationManagerSettings()
{
try
{
if (_pathAnimationManager != null)
{
_pathAnimationManager.SetAnimationFrameRate(_animationFrameRate);
_pathAnimationManager.SetCollisionDetectionAccuracy(_collisionDetectionAccuracy);
_pathAnimationManager.SetMovementSpeed(_movementSpeed);
_pathAnimationManager.SetDetectionGap(_detectionGap);
LogManager.Debug($"碰撞检测参数已更新: 动画帧率={_animationFrameRate}FPS, 精度={_collisionDetectionAccuracy:F2}m, 速度={_movementSpeed:F1}m/s, 间隙={_detectionGap:F2}m");
}
}
catch (Exception ex)
{
LogManager.Error($"更新动画管理器设置失败: {ex.Message}");
}
}
/// <summary>
/// 动画完成后更新碰撞检测状态
/// </summary>
/// <summary>
/// 动画完成后更新碰撞检测状态
/// </summary>
private void UpdateCollisionStatusAfterAnimation()
{
try
{
// 使用Idle事件监听碰撞检测完成状态替代固定延迟
const string taskId = "AnimationViewModel_WaitForCollisionResults";
IdleEventManager.Instance.RegisterOnceTask(
taskId,
() => IsCollisionDetectionComplete(), // 检查条件
() => _uiStateManager.ExecuteUIUpdateAsync(() =>
{
// 检查ClashDetectiveIntegration是否有缓存结果
var clashIntegration = _clashIntegration;
if (clashIntegration != null)
{
// 通过检查是否有任何动画相关的碰撞测试来判断是否有结果
HasCollisionResults = true; // 假设动画完成后总是有结果可查看
UpdateMainStatus("动画完成,碰撞检测已完成");
LogManager.Info("动画完成后碰撞状态已更新");
}
else
{
UpdateMainStatus("碰撞检测未就绪");
LogManager.Warning("ClashDetectiveIntegration实例不可用");
}
}), // 执行操作
10 // 高优先级
);
LogManager.Info("已注册Idle事件监听碰撞检测完成状态");
}
catch (Exception ex)
{
LogManager.Error($"动画完成后更新碰撞状态失败: {ex.Message}");
}
}
/// <summary>
/// 检查碰撞检测是否完成
/// </summary>
private bool IsCollisionDetectionComplete()
{
try
{
// 检查ClashDetectiveIntegration是否完成了碰撞测试创建
if (_clashIntegration != null)
{
// 简单的完成检查假设动画结束后1秒内碰撞检测应该完成
// 这里可以添加更具体的完成检查逻辑
return true; // 临时返回true表示可以立即处理
}
return false;
}
catch (Exception ex)
{
LogManager.Error($"检查碰撞检测完成状态失败: {ex.Message}");
return true; // 出错时认为已完成,避免无限等待
}
}
/// <summary>
/// 生成碰撞检测报告数据
@ -1962,24 +1793,8 @@ namespace NavisworksTransport.UI.WPF.ViewModels
try
{
LogManager.Info("开始清理AnimationControlViewModel资源");
// 1. 优先清理防抖定时器,避免在清理过程中触发更新
if (_parameterUpdateTimer != null)
{
try
{
_parameterUpdateTimer.Stop();
_parameterUpdateTimer.Tick -= OnParameterUpdateTimerTick;
_parameterUpdateTimer = null;
LogManager.Debug("防抖定时器清理完成");
}
catch (Exception timerEx)
{
LogManager.Warning($"清理防抖定时器时出现警告: {timerEx.Message}");
}
}
// 2. 取消事件订阅(在停止动画之前,避免事件处理中访问已释放的对象)
// 1. 取消事件订阅(在停止动画之前,避免事件处理中访问已释放的对象)
// 取消DocumentStateManager事件订阅
try