diff --git a/src/Core/Animation/PathAnimationManager.cs b/src/Core/Animation/PathAnimationManager.cs index d975c71..c71cf2e 100644 --- a/src/Core/Animation/PathAnimationManager.cs +++ b/src/Core/Animation/PathAnimationManager.cs @@ -1,6 +1,7 @@ using System; using System.Collections.Generic; using System.Linq; +using System.Text; using System.Windows.Forms; using System.Windows.Threading; using Autodesk.Navisworks.Api; @@ -80,6 +81,7 @@ namespace NavisworksTransport.Core.Animation public class PathAnimationManager { private static PathAnimationManager _instance; + private static readonly HashSet _completedCollisionTests = new HashSet(); // 记录已完成碰撞检测的动画配置 private ModelItem _animatedObject; private List _pathPoints; @@ -89,6 +91,9 @@ namespace NavisworksTransport.Core.Animation private HashSet _currentHighlightedItems; // 当前高亮的对象 private List _allCollisionResults; // 所有碰撞结果(不去重) private bool _lastHighlightState = false; // 上一帧的高亮状态 + + // === 碰撞测试优化 === + private string _currentAnimationHash = ""; // 当前动画配置的哈希值 // === 动画播放机制 === private double _frameInterval; // 帧间隔(毫秒) @@ -237,6 +242,10 @@ namespace NavisworksTransport.Core.Animation LogManager.Info("=== 坐标验证完成 ==="); + // 计算并保存当前动画配置的哈希值 + _currentAnimationHash = ComputeAnimationConfigHash(animatedObject, pathPoints); + LogManager.Info($"动画配置哈希: {_currentAnimationHash}"); + _animatedObject = animatedObject; _pathPoints = new List(pathPoints); _animationDuration = durationSeconds; @@ -889,9 +898,22 @@ namespace NavisworksTransport.Core.Animation _timeLinerManager.UpdateTaskProgress(_currentTaskId, 1.0, AnimationState.Finished); } - // 动画结束后统一创建所有碰撞测试(使用预计算的所有碰撞结果) - LogManager.Info($"动画播放完成,开始创建最终的碰撞测试汇总(基于 {_allCollisionResults.Count} 个预计算碰撞记录)..."); - ClashDetectiveIntegration.Instance.CreateAllAnimationCollisionTests(_allCollisionResults, _detectionGap); + // 检查此动画配置是否已经进行过碰撞检测 + if (!_completedCollisionTests.Contains(_currentAnimationHash) && _allCollisionResults.Count > 0) + { + LogManager.Info($"此动画配置首次完成,开始创建碰撞测试汇总(基于 {_allCollisionResults.Count} 个预计算碰撞记录)..."); + ClashDetectiveIntegration.Instance.CreateAllAnimationCollisionTests(_allCollisionResults, _detectionGap); + _completedCollisionTests.Add(_currentAnimationHash); // 记录此配置已完成碰撞检测 + LogManager.Info($"碰撞测试汇总已创建并记录,此配置后续播放将跳过碰撞检测"); + } + else if (_completedCollisionTests.Contains(_currentAnimationHash)) + { + LogManager.Info("此动画配置的碰撞测试已存在,跳过重复创建"); + } + else + { + LogManager.Info("无碰撞数据,跳过碰撞测试创建"); + } } catch (Exception ex) { @@ -2120,6 +2142,67 @@ namespace NavisworksTransport.Core.Animation } } + #region 碰撞测试优化方法 + + /// + /// 计算动画配置的哈希值(基于路径点和对象) + /// + private string ComputeAnimationConfigHash(ModelItem animatedObject, List pathPoints) + { + try + { + var sb = new StringBuilder(); + + // 包含对象名称 + sb.Append(animatedObject?.DisplayName ?? "null"); + sb.Append("|"); + + // 包含路径点信息 + if (pathPoints != null) + { + foreach (var point in pathPoints) + { + sb.Append($"{point.X:F2},{point.Y:F2},{point.Z:F2};"); + } + } + + // 计算哈希 + using (var md5 = System.Security.Cryptography.MD5.Create()) + { + var inputBytes = System.Text.Encoding.UTF8.GetBytes(sb.ToString()); + var hashBytes = md5.ComputeHash(inputBytes); + return BitConverter.ToString(hashBytes).Replace("-", ""); + } + } + catch (Exception ex) + { + LogManager.Warning($"计算动画配置哈希失败: {ex.Message}"); + return DateTime.Now.Ticks.ToString(); // 回退到时间戳 + } + } + + /// + /// 强制重新创建碰撞测试(清除指定配置的碰撞检测记录) + /// + public void ForceRecreateCollisionTest() + { + if (!string.IsNullOrEmpty(_currentAnimationHash)) + { + _completedCollisionTests.Remove(_currentAnimationHash); + LogManager.Info($"已清除动画配置 {_currentAnimationHash} 的碰撞检测记录,下次播放时将重新创建"); + } + } + + /// + /// 清除所有碰撞测试记录 + /// + public static void ClearAllCollisionTestRecords() + { + _completedCollisionTests.Clear(); + LogManager.Info("已清除所有碰撞测试记录"); + } + + #endregion #endregion }