完善timer机制
This commit is contained in:
parent
69336e2996
commit
403a7ac03b
@ -2,6 +2,7 @@ using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Windows.Forms;
|
||||
using System.Windows.Threading;
|
||||
using Autodesk.Navisworks.Api;
|
||||
using Autodesk.Navisworks.Api.Clash;
|
||||
using NavisApplication = Autodesk.Navisworks.Api.Application;
|
||||
@ -92,9 +93,7 @@ namespace NavisworksTransport.Core.Animation
|
||||
// === 动画播放机制 ===
|
||||
private double _frameInterval; // 帧间隔(毫秒)
|
||||
private DateTime _lastFrameTime = DateTime.MinValue; // 上一帧时间
|
||||
private Timer _animationTimer; // 备用Timer定时器
|
||||
private bool _isUsingTimer = false; // 是否使用Timer模式
|
||||
private const double _fpsThreshold = 10.0; // FPS阈值,低于此值切换到Timer模式
|
||||
private DispatcherTimer _animationTimer; // 备用DispatcherTimer定时器
|
||||
|
||||
// === 动画参数 ===
|
||||
private double _animationDuration = 10.0; // 动画总时长(秒)
|
||||
@ -156,16 +155,18 @@ namespace NavisworksTransport.Core.Animation
|
||||
_lastFrameTime = DateTime.MinValue;
|
||||
_fpsCounterStart = DateTime.Now;
|
||||
|
||||
// 初始化备用Timer
|
||||
_animationTimer = new Timer();
|
||||
// 初始化备用DispatcherTimer
|
||||
_animationTimer = new DispatcherTimer(DispatcherPriority.Render)
|
||||
{
|
||||
Interval = TimeSpan.FromMilliseconds(_frameInterval)
|
||||
};
|
||||
_animationTimer.Tick += OnTimerTick;
|
||||
_animationTimer.Interval = (int)_frameInterval;
|
||||
|
||||
// 初始化 TimeLiner 集成
|
||||
try
|
||||
{
|
||||
_timeLinerManager = new TimeLinerIntegrationManager();
|
||||
LogManager.Info($"PathAnimationManager 初始化完成 - Idle事件模式, 目标FPS: {_animationFrameRate}");
|
||||
LogManager.Info($"PathAnimationManager 初始化完成 - DispatcherTimer模式, 目标FPS: {_animationFrameRate}");
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
@ -633,6 +634,7 @@ namespace NavisworksTransport.Core.Animation
|
||||
// 初始化动画状态
|
||||
_animationStartTime = DateTime.Now;
|
||||
_animationFrameCount = 0; // 重置帧计数
|
||||
_currentFrameIndex = 0; // 重置当前帧索引,确保从第一帧开始
|
||||
_pausedProgress = 0.0; // 重置暂停进度
|
||||
|
||||
// 重置动画状态
|
||||
@ -640,14 +642,13 @@ namespace NavisworksTransport.Core.Animation
|
||||
_fpsFrameCount = 0;
|
||||
_fpsCounterStart = DateTime.Now;
|
||||
_frameInterval = 1000.0 / _animationFrameRate;
|
||||
_isUsingTimer = false; // 优先使用Idle事件
|
||||
_lastHighlightState = false; // 重置高亮状态
|
||||
|
||||
// 启动动画播放
|
||||
StartAnimationPlayback();
|
||||
|
||||
SetState(AnimationState.Playing);
|
||||
LogManager.Info($"动画开始播放 - {(_isUsingTimer ? "Timer" : "Idle事件")}模式");
|
||||
LogManager.Info($"动画开始播放 - DispatcherTimer模式");
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
@ -657,7 +658,7 @@ namespace NavisworksTransport.Core.Animation
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 启动动画播放(Idle事件或Timer)
|
||||
/// 启动动画播放(DispatcherTimer)
|
||||
/// </summary>
|
||||
private void StartAnimationPlayback()
|
||||
{
|
||||
@ -666,18 +667,10 @@ namespace NavisworksTransport.Core.Animation
|
||||
// 停止之前的播放
|
||||
StopAnimationPlayback();
|
||||
|
||||
if (_isUsingTimer)
|
||||
{
|
||||
// 使用Timer模式
|
||||
_animationTimer.Start();
|
||||
LogManager.Debug("[播放模式] 启动Timer模式");
|
||||
}
|
||||
else
|
||||
{
|
||||
// 使用Idle事件模式
|
||||
NavisApplication.Idle += OnApplicationIdle;
|
||||
LogManager.Debug("[播放模式] 启动Idle事件模式");
|
||||
}
|
||||
// 使用DispatcherTimer模式
|
||||
_animationTimer.Interval = TimeSpan.FromMilliseconds(_frameInterval);
|
||||
_animationTimer.Start();
|
||||
LogManager.Debug("[播放模式] 启动DispatcherTimer模式");
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
@ -686,22 +679,19 @@ namespace NavisworksTransport.Core.Animation
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 停止动画播放(清理事件和定时器)
|
||||
/// 停止动画播放(停止DispatcherTimer)
|
||||
/// </summary>
|
||||
private void StopAnimationPlayback()
|
||||
{
|
||||
try
|
||||
{
|
||||
// 停止Timer
|
||||
// 停止DispatcherTimer
|
||||
if (_animationTimer != null)
|
||||
{
|
||||
_animationTimer.Stop();
|
||||
}
|
||||
|
||||
// 注销Idle事件
|
||||
NavisApplication.Idle -= OnApplicationIdle;
|
||||
|
||||
LogManager.Debug("[播放模式] 已停止所有播放机制");
|
||||
LogManager.Debug("[播放模式] 已停止DispatcherTimer");
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
@ -710,54 +700,31 @@ namespace NavisworksTransport.Core.Animation
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Timer事件处理器 - 备用动画机制
|
||||
/// DispatcherTimer事件处理器 - 主要动画机制
|
||||
/// </summary>
|
||||
private void OnTimerTick(object sender, EventArgs e)
|
||||
{
|
||||
try
|
||||
{
|
||||
// 调用相同的动画更新逻辑
|
||||
// 处理动画帧
|
||||
ProcessAnimationFrame();
|
||||
|
||||
// 关键改进:显式请求重绘,解决卡顿
|
||||
NavisApplication.ActiveDocument.ActiveView.RequestDelayedRedraw(ViewRedrawRequests.All);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
LogManager.Error($"[Timer模式] 动画更新异常: {ex.Message}");
|
||||
LogManager.Error($"[DispatcherTimer模式] 动画更新异常: {ex.Message}");
|
||||
// 发生异常时停止动画
|
||||
ShutdownAnimation();
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 切换到Timer模式
|
||||
/// </summary>
|
||||
private void SwitchToTimerMode()
|
||||
{
|
||||
try
|
||||
{
|
||||
if (!_isUsingTimer && _currentState == AnimationState.Playing)
|
||||
{
|
||||
LogManager.Info("[播放模式] 检测到Idle事件不稳定,切换到Timer模式");
|
||||
|
||||
// 停止Idle事件
|
||||
NavisApplication.Idle -= OnApplicationIdle;
|
||||
|
||||
// 启动Timer
|
||||
_isUsingTimer = true;
|
||||
_animationTimer.Start();
|
||||
|
||||
LogManager.Info("[播放模式] 已切换到Timer模式");
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
LogManager.Error($"切换到Timer模式失败: {ex.Message}");
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 停止动画
|
||||
/// </summary>
|
||||
public void StopAnimation()
|
||||
public void CancelAnimation()
|
||||
{
|
||||
try
|
||||
{
|
||||
@ -851,7 +818,6 @@ namespace NavisworksTransport.Core.Animation
|
||||
try
|
||||
{
|
||||
if (_animationTimer != null) _animationTimer.Stop();
|
||||
NavisApplication.Idle -= OnApplicationIdle;
|
||||
}
|
||||
catch (Exception stopEx)
|
||||
{
|
||||
@ -902,6 +868,13 @@ namespace NavisworksTransport.Core.Animation
|
||||
LogManager.Info("动画完成,路径上无碰撞对象");
|
||||
}
|
||||
|
||||
// 将物体移回起点位置
|
||||
if (_pathPoints != null && _pathPoints.Count > 0 && _animatedObject != null)
|
||||
{
|
||||
UpdateObjectPosition(_pathPoints[0]);
|
||||
LogManager.Info($"动画完成,物体已移回起点位置: ({_pathPoints[0].X:F2},{_pathPoints[0].Y:F2},{_pathPoints[0].Z:F2})");
|
||||
}
|
||||
|
||||
// 直接设置为完成状态,避免中间状态切换
|
||||
SetState(AnimationState.Finished);
|
||||
|
||||
@ -1001,7 +974,7 @@ namespace NavisworksTransport.Core.Animation
|
||||
// 只在需要时停止动画,避免重复调用
|
||||
if (_currentState == AnimationState.Playing || _currentState == AnimationState.Paused)
|
||||
{
|
||||
StopAnimation(); // 停止当前动画
|
||||
CancelAnimation(); // 停止当前动画
|
||||
}
|
||||
|
||||
// 恢复对象的原始变换(安全检查Navisworks对象可用性)
|
||||
@ -1750,19 +1723,19 @@ namespace NavisworksTransport.Core.Animation
|
||||
}
|
||||
}
|
||||
|
||||
// 4. 清理Timer资源
|
||||
// 4. 清理DispatcherTimer资源
|
||||
if (_animationTimer != null)
|
||||
{
|
||||
try
|
||||
{
|
||||
_animationTimer.Stop();
|
||||
_animationTimer.Dispose();
|
||||
// DispatcherTimer不需要Dispose
|
||||
_animationTimer = null;
|
||||
LogManager.Info("动画Timer资源已清理");
|
||||
LogManager.Info("DispatcherTimer资源已清理");
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
LogManager.Warning($"清理Timer资源时出现警告: {ex.Message}");
|
||||
LogManager.Warning($"清理DispatcherTimer资源时出现警告: {ex.Message}");
|
||||
}
|
||||
}
|
||||
|
||||
@ -1893,7 +1866,16 @@ namespace NavisworksTransport.Core.Animation
|
||||
public void SetAnimationFrameRate(int frameRate)
|
||||
{
|
||||
_animationFrameRate = Math.Max(10, Math.Min(60, frameRate)); // 限制在10-60FPS之间
|
||||
LogManager.Info($"动画帧率设置为: {_animationFrameRate}FPS");
|
||||
_frameInterval = 1000.0 / _animationFrameRate; // 重新计算帧间隔
|
||||
|
||||
// 动态更新DispatcherTimer间隔
|
||||
if (_animationTimer != null)
|
||||
{
|
||||
_animationTimer.Interval = TimeSpan.FromMilliseconds(_frameInterval);
|
||||
LogManager.Info($"DispatcherTimer间隔已更新: {_frameInterval:F1}ms");
|
||||
}
|
||||
|
||||
LogManager.Info($"动画帧率设置为: {_animationFrameRate}FPS (间隔: {_frameInterval:F1}ms)");
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@ -1978,7 +1960,7 @@ namespace NavisworksTransport.Core.Animation
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Idle事件处理器 - 新的动画核心
|
||||
/// DispatcherTimer动画处理核心
|
||||
/// </summary>
|
||||
/// <summary>
|
||||
/// 根据当前帧索引更新碰撞高亮(状态跟踪优化版本)
|
||||
@ -2031,7 +2013,7 @@ namespace NavisworksTransport.Core.Animation
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 统一的动画帧处理逻辑(Idle事件和Timer共用)
|
||||
/// 统一的动画帧处理逻辑(DispatcherTimer专用)
|
||||
/// </summary>
|
||||
private void ProcessAnimationFrame()
|
||||
{
|
||||
@ -2049,16 +2031,8 @@ namespace NavisworksTransport.Core.Animation
|
||||
return;
|
||||
}
|
||||
|
||||
// 帧率控制(仅对Idle事件有效,Timer有自己的间隔控制)
|
||||
// DispatcherTimer已经控制了调用间隔,无需手动帧率控制
|
||||
var now = DateTime.Now;
|
||||
if (!_isUsingTimer) // Idle事件模式需要手动控制帧率
|
||||
{
|
||||
var elapsed = (now - _lastFrameTime).TotalMilliseconds;
|
||||
if (elapsed < _frameInterval)
|
||||
{
|
||||
return; // 还没到下一帧时间,跳过本次处理
|
||||
}
|
||||
}
|
||||
|
||||
// 计算下一帧索引(考虑播放方向和速度)
|
||||
int nextFrameIndex = _currentFrameIndex;
|
||||
@ -2125,23 +2099,9 @@ namespace NavisworksTransport.Core.Animation
|
||||
UpdateFPSCounterAndCheckSwitch();
|
||||
}
|
||||
|
||||
private void OnApplicationIdle(object sender, EventArgs e)
|
||||
{
|
||||
try
|
||||
{
|
||||
// 调用统一的帧处理逻辑
|
||||
ProcessAnimationFrame();
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
LogManager.Error($"[Idle模式] 动画更新异常: {ex.Message}");
|
||||
// 发生异常时停止动画,避免持续错误
|
||||
ShutdownAnimation();
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 更新FPS计数器并检查是否需要切换播放模式
|
||||
/// 更新FPS计数器(DispatcherTimer模式)
|
||||
/// </summary>
|
||||
private void UpdateFPSCounterAndCheckSwitch()
|
||||
{
|
||||
@ -2152,14 +2112,7 @@ namespace NavisworksTransport.Core.Animation
|
||||
if (elapsed >= 1.0)
|
||||
{
|
||||
_actualFPS = _fpsFrameCount / elapsed;
|
||||
LogManager.Debug($"[性能监控] 实际FPS: {_actualFPS:F1} (目标: {_animationFrameRate}) - {(_isUsingTimer ? "Timer" : "Idle")}模式");
|
||||
|
||||
// 检查是否需要切换到Timer模式
|
||||
if (!_isUsingTimer && _actualFPS < _fpsThreshold)
|
||||
{
|
||||
LogManager.Warning($"[性能监控] FPS过低 ({_actualFPS:F1} < {_fpsThreshold}),切换到Timer模式");
|
||||
SwitchToTimerMode();
|
||||
}
|
||||
LogManager.Debug($"[性能监控] 实际FPS: {_actualFPS:F1} (目标: {_animationFrameRate}) - DispatcherTimer模式");
|
||||
|
||||
// 重置计数器
|
||||
_fpsFrameCount = 0;
|
||||
|
||||
@ -400,9 +400,7 @@ namespace NavisworksTransport
|
||||
resultCount++;
|
||||
|
||||
try
|
||||
{
|
||||
LogManager.Info($"[分组测试-{resultCount:00}] 处理碰撞: {collision.Item1?.DisplayName} <-> {collision.Item2?.DisplayName}");
|
||||
|
||||
{
|
||||
// 临时移动动画对象到碰撞位置以执行测试
|
||||
var testAnimatedObject = collision.Item1;
|
||||
var modelItems = new ModelItemCollection { testAnimatedObject };
|
||||
@ -456,7 +454,6 @@ namespace NavisworksTransport
|
||||
copyTest.SelectionA.PrimitiveTypes = PrimitiveTypes.Triangles | PrimitiveTypes.Lines | PrimitiveTypes.Points;
|
||||
copyTest.SelectionB.PrimitiveTypes = PrimitiveTypes.Triangles | PrimitiveTypes.Lines | PrimitiveTypes.Points;
|
||||
_documentClash.TestsData.TestsEditTestFromCopy(addedTempTest, copyTest);
|
||||
LogManager.Debug($"[分组测试-{resultCount:00}] 几何类型设置完成");
|
||||
}
|
||||
catch (Exception geomEx)
|
||||
{
|
||||
@ -469,9 +466,7 @@ namespace NavisworksTransport
|
||||
// 获取刷新后的测试结果
|
||||
var refreshedTempTest = _documentClash.TestsData.Tests.FirstOrDefault(t => t.DisplayName == tempTestName) as ClashTest;
|
||||
if (refreshedTempTest != null && refreshedTempTest.Children.Count > 0)
|
||||
{
|
||||
LogManager.Info($"[分组测试-{resultCount:00}] 临时测试检测到 {refreshedTempTest.Children.Count} 个碰撞");
|
||||
|
||||
{
|
||||
// 将碰撞结果复制到分组中,并设置唯一名称
|
||||
int subResultIndex = 1;
|
||||
foreach (var child in refreshedTempTest.Children)
|
||||
@ -488,22 +483,15 @@ namespace NavisworksTransport
|
||||
copiedResult.DisplayName = $"路径碰撞#{resultCount:00}-{subResultIndex:00}_{timeStamp}: {object1Name} ↔ {object2Name}";
|
||||
|
||||
collisionGroup.Children.Add(copiedResult);
|
||||
LogManager.Debug($"[分组测试-{resultCount:00}] 复制碰撞结果到分组: {copiedResult.DisplayName}");
|
||||
subResultIndex++;
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
LogManager.Info($"[分组测试-{resultCount:00}] 临时测试未检测到碰撞,跳过此项");
|
||||
// 🔧 修复:如果没有检测到碰撞,直接跳过,不创建手动结果
|
||||
}
|
||||
|
||||
// 删除临时测试
|
||||
try
|
||||
{
|
||||
_documentClash.TestsData.TestsRemove(refreshedTempTest ?? addedTempTest);
|
||||
LogManager.Debug($"[分组测试-{resultCount:00}] 临时测试已清理");
|
||||
}
|
||||
catch (Exception cleanEx)
|
||||
{
|
||||
@ -522,7 +510,6 @@ namespace NavisworksTransport
|
||||
if (collisionGroup.Children.Count > 0)
|
||||
{
|
||||
_documentClash.TestsData.TestsAddCopy(addedMainTest, collisionGroup);
|
||||
LogManager.Info($"[分组测试] 分组已添加到主测试,包含 {collisionGroup.Children.Count} 个碰撞结果");
|
||||
}
|
||||
else
|
||||
{
|
||||
@ -531,7 +518,6 @@ namespace NavisworksTransport
|
||||
|
||||
// 提交事务
|
||||
transaction.Commit();
|
||||
LogManager.Info("[分组测试] 事务已提交,测试创建完成");
|
||||
}
|
||||
}
|
||||
catch (Exception groupEx)
|
||||
|
||||
@ -287,7 +287,7 @@ namespace NavisworksTransport.UI.WPF.ViewModels
|
||||
{
|
||||
try
|
||||
{
|
||||
_pathAnimationManager.StopAnimation(); // 这会将状态设置为Stopped,需要重新生成动画
|
||||
_pathAnimationManager.CancelAnimation(); // 这会将状态设置为Stopped,需要重新生成动画
|
||||
LogManager.Info("移动物体更改,已清除之前生成的动画");
|
||||
}
|
||||
catch (Exception ex)
|
||||
@ -712,7 +712,7 @@ namespace NavisworksTransport.UI.WPF.ViewModels
|
||||
});
|
||||
|
||||
// 停止当前动画
|
||||
_pathAnimationManager.StopAnimation();
|
||||
_pathAnimationManager.CancelAnimation();
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
@ -980,7 +980,7 @@ namespace NavisworksTransport.UI.WPF.ViewModels
|
||||
{
|
||||
try
|
||||
{
|
||||
_pathAnimationManager.StopAnimation(); // 这会将状态设置为Stopped,需要重新生成动画
|
||||
_pathAnimationManager.CancelAnimation(); // 这会将状态设置为Stopped,需要重新生成动画
|
||||
LogManager.Info("路径更改,已清除之前生成的动画");
|
||||
}
|
||||
catch (Exception ex)
|
||||
@ -1159,7 +1159,7 @@ namespace NavisworksTransport.UI.WPF.ViewModels
|
||||
{
|
||||
try
|
||||
{
|
||||
_pathAnimationManager.StopAnimation();
|
||||
_pathAnimationManager.CancelAnimation();
|
||||
LogManager.Info("已停止当前播放的动画");
|
||||
}
|
||||
catch (Exception stopEx)
|
||||
@ -1909,7 +1909,7 @@ namespace NavisworksTransport.UI.WPF.ViewModels
|
||||
// 停止动画
|
||||
if (_pathAnimationManager != null && _pathAnimationManager.IsAnimating)
|
||||
{
|
||||
_pathAnimationManager.StopAnimation();
|
||||
_pathAnimationManager.CancelAnimation();
|
||||
}
|
||||
|
||||
// 清空选中对象
|
||||
|
||||
Loading…
Reference in New Issue
Block a user