diff --git a/NavisworksTransportPlugin.csproj b/NavisworksTransportPlugin.csproj index 25b291c..a60de34 100644 --- a/NavisworksTransportPlugin.csproj +++ b/NavisworksTransportPlugin.csproj @@ -144,7 +144,7 @@ - + diff --git a/src/Commands/ViewCollisionReportCommand.cs b/src/Commands/GenerateCollisionReportCommand.cs similarity index 95% rename from src/Commands/ViewCollisionReportCommand.cs rename to src/Commands/GenerateCollisionReportCommand.cs index 6ff06d9..72ba2ee 100644 --- a/src/Commands/ViewCollisionReportCommand.cs +++ b/src/Commands/GenerateCollisionReportCommand.cs @@ -84,12 +84,18 @@ namespace NavisworksTransport.Commands // 新增:被撞物体清单 public List CollidedObjectsList { get; set; } = new List(); public int UniqueCollidedObjectsCount { get; set; } + + // 新增:动画参数 + public string PathName { get; set; } = "未知路径"; + public int FrameRate { get; set; } = 30; + public double Duration { get; set; } = 10.0; + public double DetectionGap { get; set; } = 0.05; } /// - /// 查看碰撞报告Command + /// 生成碰撞报告Command /// - public class ViewCollisionReportCommand : CommandBase + public class GenerateCollisionReportCommand : CommandBase { #region 静态缓存机制 @@ -107,8 +113,8 @@ namespace NavisworksTransport.Commands private readonly CollisionReportParameters _parameters; - public ViewCollisionReportCommand(CollisionReportParameters parameters = null) - : base("ViewCollisionReport", "查看碰撞报告", "生成并显示详细的碰撞检测报告") + public GenerateCollisionReportCommand(CollisionReportParameters parameters = null) + : base("GenerateCollisionReport", "生成碰撞报告", "生成并显示详细的碰撞检测报告") { _parameters = parameters ?? new CollisionReportParameters(); } @@ -177,6 +183,17 @@ namespace NavisworksTransport.Commands result.CollidedObjectsList = collisionData.UniqueCollidedObjects.OrderBy(x => x).ToList(); result.UniqueCollidedObjectsCount = collisionData.UniqueCollidedObjects.Count; + // 新增:从动画管理器获取动画参数 + var animationManager = Core.Animation.PathAnimationManager.GetInstance(); + if (animationManager != null) + { + result.FrameRate = animationManager.AnimationFrameRate; + result.Duration = animationManager.AnimationDuration; + result.DetectionGap = animationManager.DetectionGap; + // PathName需要从动画管理器获取 + result.PathName = animationManager.PathName ?? "未知路径"; + } + LogManager.Info($"碰撞报告计数 - 检查点: {result.AnimationCollisions}, Clash Detective: {result.TotalCollisions}"); UpdateProgress(70, "生成报告内容..."); @@ -578,21 +595,6 @@ namespace NavisworksTransport.Commands report.AppendLine(); } - // 按状态分类 - var newCollisions = collisions.Where(c => c.Status == ClashResultStatus.New).ToList(); - var activeCollisions = collisions.Where(c => c.Status == ClashResultStatus.Active).ToList(); - var reviewedCollisions = collisions.Where(c => c.Status == ClashResultStatus.Reviewed).ToList(); - var approvedCollisions = collisions.Where(c => c.Status == ClashResultStatus.Approved).ToList(); - var resolvedCollisions = collisions.Where(c => c.Status == ClashResultStatus.Resolved).ToList(); - - report.AppendLine("=== 按状态分类 ==="); - report.AppendLine($"新发现: {newCollisions.Count}"); - report.AppendLine($"活跃: {activeCollisions.Count}"); - report.AppendLine($"已审阅: {reviewedCollisions.Count}"); - report.AppendLine($"已批准: {approvedCollisions.Count}"); - report.AppendLine($"已解决: {resolvedCollisions.Count}"); - report.AppendLine(); - // 详细信息 if (includeDetails && collisions.Count > 0) { @@ -755,9 +757,9 @@ namespace NavisworksTransport.Commands /// /// 创建综合报告命令 /// - public static ViewCollisionReportCommand CreateComprehensive(bool autoHighlight = false) + public static GenerateCollisionReportCommand CreateComprehensive(bool autoHighlight = false) { - return new ViewCollisionReportCommand(new CollisionReportParameters + return new GenerateCollisionReportCommand(new CollisionReportParameters { Type = CollisionReportParameters.ReportType.Comprehensive, IncludeDetails = true, diff --git a/src/Core/Animation/PathAnimationManager.cs b/src/Core/Animation/PathAnimationManager.cs index 00d8386..0fed9d2 100644 --- a/src/Core/Animation/PathAnimationManager.cs +++ b/src/Core/Animation/PathAnimationManager.cs @@ -116,6 +116,8 @@ namespace NavisworksTransport.Core.Animation private double _movementSpeed = 1.0; // 运动速度(默认1米/秒) private double _detectionGap = 0.05; // 检测间隙(默认0.05米) private string _pathName = "未知路径"; // 路径名称 + private string _currentRouteId = null; // 当前路由ID + private string _animatedObjectName = null; // 动画对象名称 // === 双向播放和步进控制 === private int _playbackDirection = 1; // 播放方向:1=正向,-1=反向 @@ -915,7 +917,15 @@ namespace NavisworksTransport.Core.Animation if (!_completedCollisionTests.Contains(_currentAnimationHash) && _allCollisionResults.Count > 0) { LogManager.Info($"此动画配置首次完成,开始创建碰撞测试汇总(基于 {_allCollisionResults.Count} 个预计算碰撞记录)..."); - ClashDetectiveIntegration.Instance.CreateAllAnimationCollisionTests(_allCollisionResults, _detectionGap, _pathName); + ClashDetectiveIntegration.Instance.CreateAllAnimationCollisionTests( + _allCollisionResults, + _detectionGap, + _pathName, + _currentRouteId, + _animatedObjectName, + _animationFrameRate, + _animationDuration + ); _completedCollisionTests.Add(_currentAnimationHash); // 记录此配置已完成碰撞检测 LogManager.Info($"碰撞测试汇总已创建并记录,此配置后续播放将跳过碰撞检测"); } @@ -1962,6 +1972,16 @@ namespace NavisworksTransport.Core.Animation /// public double DetectionGap => _detectionGap; + /// + /// 获取路径名称 + /// + public string PathName => _pathName; + + /// + /// 获取动画时长 + /// + public double AnimationDuration => _animationDuration; + /// /// 设置并触发状态变更事件 /// @@ -1982,9 +2002,16 @@ namespace NavisworksTransport.Core.Animation /// 路径点列表 /// 动画持续时间(秒) /// 路径名称 - public void CreateAnimation(ModelItem animatedObject, List pathPoints, double durationSeconds = 10.0, string pathName = "未知路径") + /// 路由ID + public void CreateAnimation(ModelItem animatedObject, List pathPoints, double durationSeconds = 10.0, string pathName = "未知路径", string routeId = null) { _pathName = pathName; // 存储路径名称 + _currentRouteId = routeId; // 存储路由ID + _animatedObjectName = animatedObject?.DisplayName ?? "未知对象"; // 存储动画对象名称 + + // 添加调试日志 + LogManager.Info($"[PathAnimationManager.CreateAnimation] 接收到参数: pathName='{pathName}', routeId='{routeId}', animatedObjectName='{_animatedObjectName}'"); + LogManager.Info($"[PathAnimationManager.CreateAnimation] 存储的值: _pathName='{_pathName}', _currentRouteId='{_currentRouteId}'"); SetupAnimation(animatedObject, pathPoints, durationSeconds); SetState(AnimationState.Ready); } diff --git a/src/Core/Collision/ClashDetectiveIntegration.cs b/src/Core/Collision/ClashDetectiveIntegration.cs index a0e8f9b..690612d 100644 --- a/src/Core/Collision/ClashDetectiveIntegration.cs +++ b/src/Core/Collision/ClashDetectiveIntegration.cs @@ -244,7 +244,13 @@ namespace NavisworksTransport /// 预计算碰撞结果 /// 检测间隙容差 /// 路径名称 - public void CreateAllAnimationCollisionTests(List precomputedCollisions, double detectionGap = 0.05, string pathName = "未知路径") + /// 路由ID + /// 动画对象名称 + /// 帧率 + /// 动画时长 + public void CreateAllAnimationCollisionTests(List precomputedCollisions, double detectionGap = 0.05, + string pathName = "未知路径", string routeId = null, string animatedObjectName = null, + int frameRate = 30, double duration = 10.0) { try { @@ -587,7 +593,7 @@ namespace NavisworksTransport LogManager.Info($"Clash Detective权威结果: {_clashDetectiveCollisionCount}个碰撞 (最终权威数据)"); LogManager.Info($"统计说明: 动画过程使用简单包围盒检测,Clash Detective使用精确几何体检测"); LogManager.Info($"=== 统计分离完成 ==="); - + LogManager.Info("=== 动画碰撞测试(分组方案)完成 ==="); // 触发碰撞检测完成事件,通知生成报告 @@ -597,6 +603,10 @@ namespace NavisworksTransport var eventArgs = new CollisionDetectedEventArgs(validCollisions); OnCollisionDetected(eventArgs); } + else + { + LogManager.Info("没有碰撞,不生成报告,不保存数据库"); + } } } catch (Exception ex) diff --git a/src/Core/PathDatabase.cs b/src/Core/PathDatabase.cs index ea8dee5..9a57780 100644 --- a/src/Core/PathDatabase.cs +++ b/src/Core/PathDatabase.cs @@ -78,19 +78,20 @@ namespace NavisworksTransport ) "); - // 2. 碰撞结果表 + // 2. 碰撞报告表(替换原有的CollisionResults表) ExecuteNonQuery(@" - CREATE TABLE IF NOT EXISTS CollisionResults ( + CREATE TABLE IF NOT EXISTS CollisionReports ( Id INTEGER PRIMARY KEY AUTOINCREMENT, - RouteId TEXT NOT NULL, - Item1Name TEXT, - Item2Name TEXT, - CenterX REAL, - CenterY REAL, - CenterZ REAL, - Distance REAL, - DetectedTime DATETIME, - FOREIGN KEY(RouteId) REFERENCES PathRoutes(Id) ON DELETE CASCADE + RouteId TEXT, + PathName TEXT, + AnimatedObjectName TEXT, + UniqueCollidedObjectsCount INTEGER, + FrameRate INTEGER, + Duration REAL, + DetectionGap REAL, + AnimationCollisionCount INTEGER, + ClashDetectiveCollisionCount INTEGER, + ReportTime DATETIME ) "); @@ -124,7 +125,7 @@ namespace NavisworksTransport "); // 创建索引 - ExecuteNonQuery("CREATE INDEX IF NOT EXISTS idx_collisions_route ON CollisionResults(RouteId)"); + ExecuteNonQuery("CREATE INDEX IF NOT EXISTS idx_reports_route ON CollisionReports(RouteId)"); ExecuteNonQuery("CREATE INDEX IF NOT EXISTS idx_pathpoints_route ON PathPoints(RouteId)"); } @@ -205,7 +206,48 @@ namespace NavisworksTransport } /// - /// 保存路径的碰撞结果 + /// 保存碰撞报告 + /// + public void SaveCollisionReport(string routeId, string pathName, string animatedObjectName, + int uniqueCollidedObjectsCount, int frameRate, double duration, double detectionGap, + int animationCollisionCount, int clashDetectiveCollisionCount) + { + try + { + var sql = @" + INSERT INTO CollisionReports + (RouteId, PathName, AnimatedObjectName, UniqueCollidedObjectsCount, FrameRate, Duration, + DetectionGap, AnimationCollisionCount, ClashDetectiveCollisionCount, ReportTime) + VALUES (@routeId, @pathName, @animatedObjectName, @uniqueCollidedObjectsCount, @frameRate, @duration, + @detectionGap, @animationCount, @clashCount, @reportTime) + "; + + using (var cmd = new SQLiteCommand(sql, _connection)) + { + cmd.Parameters.AddWithValue("@routeId", routeId ?? ""); + cmd.Parameters.AddWithValue("@pathName", pathName ?? "未知路径"); + cmd.Parameters.AddWithValue("@animatedObjectName", animatedObjectName ?? "未知对象"); + cmd.Parameters.AddWithValue("@uniqueCollidedObjectsCount", uniqueCollidedObjectsCount); + cmd.Parameters.AddWithValue("@frameRate", frameRate); + cmd.Parameters.AddWithValue("@duration", duration); + cmd.Parameters.AddWithValue("@detectionGap", detectionGap); + cmd.Parameters.AddWithValue("@animationCount", animationCollisionCount); + cmd.Parameters.AddWithValue("@clashCount", clashDetectiveCollisionCount); + cmd.Parameters.AddWithValue("@reportTime", DateTime.Now); + cmd.ExecuteNonQuery(); + } + + LogManager.Info($"碰撞报告已保存: 路径={pathName}, 碰撞构件={uniqueCollidedObjectsCount}, 动画碰撞={animationCollisionCount}, ClashDetective碰撞={clashDetectiveCollisionCount}"); + } + catch (Exception ex) + { + LogManager.Error($"保存碰撞报告失败: {ex.Message}", ex); + throw; + } + } + + /// + /// 保存路径的碰撞结果(已废弃,保留以兼容旧代码) /// public void SaveCollisions(string routeId, List collisions) { diff --git a/src/Core/PathPlanningManager.cs b/src/Core/PathPlanningManager.cs index 197744d..1b0eb88 100644 --- a/src/Core/PathPlanningManager.cs +++ b/src/Core/PathPlanningManager.cs @@ -2843,6 +2843,18 @@ namespace NavisworksTransport #endregion + #region 公共访问方法 + + /// + /// 获取PathDatabase实例 + /// + public PathDatabase GetPathDatabase() + { + return _pathDatabase; + } + + #endregion + #region 自动路径规划辅助方法 /// diff --git a/src/UI/WPF/Models/PathRouteViewModel.cs b/src/UI/WPF/Models/PathRouteViewModel.cs index c1a5073..982b570 100644 --- a/src/UI/WPF/Models/PathRouteViewModel.cs +++ b/src/UI/WPF/Models/PathRouteViewModel.cs @@ -156,6 +156,7 @@ namespace NavisworksTransport.UI.WPF.ViewModels { #region 私有字段 + private string _id; private string _name; private ObservableCollection _points; private bool _isActive; @@ -176,6 +177,15 @@ namespace NavisworksTransport.UI.WPF.ViewModels #region 公共属性 + /// + /// 路径ID + /// + public string Id + { + get => _id; + set => SetProperty(ref _id, value); + } + /// /// 路径名称 /// @@ -380,6 +390,7 @@ namespace NavisworksTransport.UI.WPF.ViewModels /// private void InitializeDefaults() { + _id = Guid.NewGuid().ToString(); _name = "新路径"; _description = ""; _isActive = false; diff --git a/src/UI/WPF/ViewModels/AnimationControlViewModel.cs b/src/UI/WPF/ViewModels/AnimationControlViewModel.cs index ec99dc0..1714109 100644 --- a/src/UI/WPF/ViewModels/AnimationControlViewModel.cs +++ b/src/UI/WPF/ViewModels/AnimationControlViewModel.cs @@ -78,7 +78,8 @@ namespace NavisworksTransport.UI.WPF.ViewModels // 碰撞检测相关字段 private bool _hasCollisionResults = false; - + private CollisionReportResult _lastGeneratedReport; // 缓存最后生成的报告 + // 碰撞检测参数字段 private double _detectionGap = 0.05; // 检测间隙(米) private int _animationFrameRate = 30; // 动画帧率(FPS) @@ -456,8 +457,8 @@ namespace NavisworksTransport.UI.WPF.ViewModels // 设置主ViewModel引用到基类 SetMainViewModel(mainViewModel); - // 初始化管理器 - _pathAnimationManager = new NavisworksTransport.Core.Animation.PathAnimationManager(); + // 初始化管理器 - 使用单例模式确保与GenerateCollisionReportCommand使用同一实例 + _pathAnimationManager = NavisworksTransport.Core.Animation.PathAnimationManager.GetInstance(); _clashIntegration = ClashDetectiveIntegration.Instance; _uiStateManager = UIStateManager.Instance; @@ -680,7 +681,7 @@ namespace NavisworksTransport.UI.WPF.ViewModels /// - /// 查看碰撞报告命令 + /// 查看碰撞报告命令(显示已缓存的报告) /// private async Task ExecuteViewCollisionReport() { @@ -692,23 +693,42 @@ namespace NavisworksTransport.UI.WPF.ViewModels try { - UpdateMainStatus("正在生成碰撞报告...", -1, true); - LogManager.Info("开始生成碰撞检测详细报告"); - - // 直接调用完整的ViewCollisionReportCommand生成详细报告(在主线程上执行COM操作) - var viewReportCommand = NavisworksTransport.Commands.ViewCollisionReportCommand.CreateComprehensive(); - var result = await viewReportCommand.ExecuteAsync(); - - if (result.IsSuccess) + // 检查是否有已缓存的报告 + if (_lastGeneratedReport == null) { - UpdateMainStatus("碰撞报告已生成"); - LogManager.Info("碰撞报告生成完成并已显示"); + UpdateMainStatus("报告尚未生成,请等待碰撞检测完成"); + LogManager.Warning("尝试查看报告但缓存为空"); + return; } - else + + UpdateMainStatus("正在显示碰撞报告...", -1, true); + LogManager.Info("开始显示已缓存的碰撞报告"); + + // 在UI线程上显示缓存的报告 + await _uiStateManager.ExecuteUIUpdateAsync(() => { - UpdateMainStatus($"报告生成失败: {result.ErrorMessage}"); - LogManager.Error($"碰撞报告生成失败: {result.ErrorMessage}"); - } + try + { + // 使用WPF碰撞报告对话框直接显示缓存的报告 + var reportDialog = NavisworksTransport.UI.WPF.Views.CollisionReportDialog.ShowReport(_lastGeneratedReport); + + if (reportDialog != null) + { + UpdateMainStatus("碰撞报告已显示"); + LogManager.Info("成功显示缓存的碰撞报告"); + } + else + { + UpdateMainStatus("显示报告对话框失败"); + LogManager.Error("CollisionReportDialog.ShowReport返回null"); + } + } + catch (Exception dialogEx) + { + UpdateMainStatus($"显示报告失败: {dialogEx.Message}"); + LogManager.Error($"显示WPF报告对话框失败: {dialogEx.Message}"); + } + }); } catch (Exception ex) { @@ -902,7 +922,17 @@ namespace NavisworksTransport.UI.WPF.ViewModels public void SetCurrentPath(PathRouteViewModel pathRoute) { CurrentPathRoute = pathRoute; - + + // 添加调试日志 + if (pathRoute != null) + { + LogManager.Info($"[AnimationControlViewModel] 设置当前路径: 名称='{pathRoute.Name}', ID='{pathRoute.Id}', 点数={pathRoute.Points?.Count ?? 0}"); + } + else + { + LogManager.Info("[AnimationControlViewModel] 清空当前路径"); + } + // 路径改变时清除已生成的动画(如果有的话) if (_pathAnimationManager != null && (_pathAnimationManager.CurrentState == NavisworksTransport.Core.Animation.AnimationState.Ready || @@ -1009,15 +1039,98 @@ namespace NavisworksTransport.UI.WPF.ViewModels /// - /// 处理碰撞检测事件 + /// 处理碰撞检测事件 - 自动生成报告并保存数据库 /// - private void OnCollisionDetected(object sender, CollisionDetectedEventArgs e) + private async void OnCollisionDetected(object sender, CollisionDetectedEventArgs e) { HasCollisionResults = e.Results.Count > 0; - var summary = e.Results.Count > 0 - ? $"发现 {e.Results.Count} 个碰撞点" - : "未发现碰撞"; - UpdateMainStatus(summary); + + if (e.Results.Count > 0) + { + try + { + UpdateMainStatus($"发现 {e.Results.Count} 个碰撞点,正在生成报告...", -1, true); + LogManager.Info($"碰撞检测完成,发现 {e.Results.Count} 个碰撞,开始自动生成报告"); + + // 自动生成碰撞报告 + var generateReportCommand = NavisworksTransport.Commands.GenerateCollisionReportCommand.CreateComprehensive(); + var result = await generateReportCommand.ExecuteAsync(); + + if (result.IsSuccess && result is PathPlanningResult reportResult) + { + // 缓存报告结果,供后续查看使用 + _lastGeneratedReport = reportResult.Data; + + // 保存到数据库 + await SaveCollisionReportToDatabase(reportResult.Data); + + UpdateMainStatus($"✅ 碰撞报告已生成并保存:{e.Results.Count} 个碰撞"); + LogManager.Info("碰撞报告已自动生成并保存到数据库"); + } + else + { + UpdateMainStatus($"发现 {e.Results.Count} 个碰撞点(报告生成失败)"); + LogManager.Error($"自动生成碰撞报告失败: {result.ErrorMessage}"); + } + } + catch (Exception ex) + { + LogManager.Error($"处理碰撞检测事件失败: {ex.Message}", ex); + UpdateMainStatus($"发现 {e.Results.Count} 个碰撞点(报告生成异常)"); + } + } + else + { + UpdateMainStatus("未发现碰撞"); + _lastGeneratedReport = null; + } + } + + /// + /// 保存碰撞报告到数据库 + /// + private async Task SaveCollisionReportToDatabase(CollisionReportResult reportResult) + { + try + { + var pathPlanningManager = PathPlanningManager.Instance; + var pathDatabase = pathPlanningManager?.GetPathDatabase(); + + if (pathDatabase != null && reportResult != null) + { + // 获取路由ID + string routeId = CurrentPathRoute?.Id ?? ""; + + // 从报告中获取所有需要的数据 + await Task.Run(() => + { + pathDatabase.SaveCollisionReport( + routeId, + reportResult.PathName, + SelectedAnimatedObjectName ?? "未知对象", + reportResult.UniqueCollidedObjectsCount, + reportResult.FrameRate, + reportResult.Duration, + reportResult.DetectionGap, + reportResult.AnimationCollisions, + reportResult.TotalCollisions + ); + }); + + LogManager.Info($"碰撞报告已保存到数据库 - 路径:{reportResult.PathName}, " + + $"碰撞构件:{reportResult.UniqueCollidedObjectsCount}, " + + $"动画碰撞:{reportResult.AnimationCollisions}, " + + $"ClashDetective:{reportResult.TotalCollisions}"); + } + else + { + LogManager.Warning("无法获取PathDatabase实例或报告数据为空,碰撞报告未保存到数据库"); + } + } + catch (Exception ex) + { + LogManager.Error($"保存碰撞报告到数据库失败: {ex.Message}", ex); + } } /// @@ -1295,8 +1408,11 @@ namespace NavisworksTransport.UI.WPF.ViewModels // 将PathRouteViewModel的点转换为Point3D列表 var pathPoints = CurrentPathRoute.Points.Select(p => new Point3D(p.X, p.Y, p.Z)).ToList(); + // 添加调试日志 + LogManager.Info($"[ExecuteGenerateAnimation] 准备创建动画: 路径名称='{CurrentPathRoute.Name}', ID='{CurrentPathRoute.Id}', 动画对象='{SelectedAnimatedObject.DisplayName}'"); + // 使用PathAnimationManager创建物体动画(真正的物体移动动画,会设置状态为Ready) - _pathAnimationManager.CreateAnimation(SelectedAnimatedObject, pathPoints, AnimationDuration, CurrentPathRoute.Name); + _pathAnimationManager.CreateAnimation(SelectedAnimatedObject, pathPoints, AnimationDuration, CurrentPathRoute.Name, CurrentPathRoute.Id); // 更新状态 - 使用新的按钮状态更新方法 UpdateAnimationButtonStates(); @@ -1815,17 +1931,20 @@ namespace NavisworksTransport.UI.WPF.ViewModels } } - // 3. 清理动画管理器(PathAnimationManager.Dispose内部已经优化了安全清理) + // 3. 不再清理PathAnimationManager - 现在使用单例模式,由应用程序生命周期管理 + // 注意:PathAnimationManager.GetInstance()返回的是单例实例, + // 不应该在这里Dispose,否则会影响其他使用该单例的地方 if (_pathAnimationManager != null) { try { - _pathAnimationManager.Dispose(); - LogManager.Debug("PathAnimationManager清理完成"); + // 只清理事件订阅和重置状态,不调用Dispose + _pathAnimationManager.ResetAnimation(); + LogManager.Debug("PathAnimationManager状态重置完成"); } - catch (Exception disposeEx) + catch (Exception resetEx) { - LogManager.Warning($"清理PathAnimationManager时出现警告: {disposeEx.Message}"); + LogManager.Warning($"重置PathAnimationManager状态时出现警告: {resetEx.Message}"); } } diff --git a/src/UI/WPF/ViewModels/CollisionReportViewModel.cs b/src/UI/WPF/ViewModels/CollisionReportViewModel.cs index 6cf954b..c960107 100644 --- a/src/UI/WPF/ViewModels/CollisionReportViewModel.cs +++ b/src/UI/WPF/ViewModels/CollisionReportViewModel.cs @@ -80,6 +80,10 @@ namespace NavisworksTransport.UI.WPF.ViewModels private string _movingObjectInfo; private ObservableCollection _collidedObjectsList; private int _uniqueCollidedObjectsCount; + private string _pathName; + private int _frameRate; + private double _duration; + private double _detectionGap; #endregion @@ -203,6 +207,42 @@ namespace NavisworksTransport.UI.WPF.ViewModels set => SetProperty(ref _uniqueCollidedObjectsCount, value); } + /// + /// 路径名称 + /// + public string PathName + { + get => _pathName; + set => SetProperty(ref _pathName, value); + } + + /// + /// 动画帧率 + /// + public int FrameRate + { + get => _frameRate; + set => SetProperty(ref _frameRate, value); + } + + /// + /// 动画时长 + /// + public double Duration + { + get => _duration; + set => SetProperty(ref _duration, value); + } + + /// + /// 检测间隙 + /// + public double DetectionGap + { + get => _detectionGap; + set => SetProperty(ref _detectionGap, value); + } + #endregion #region 命令属性 @@ -217,10 +257,6 @@ namespace NavisworksTransport.UI.WPF.ViewModels /// public ICommand CloseCommand { get; } - /// - /// 刷新报告命令 - /// - public ICommand RefreshReportCommand { get; } /// /// 高亮碰撞对象命令 @@ -242,7 +278,6 @@ namespace NavisworksTransport.UI.WPF.ViewModels // 初始化命令 ExportReportCommand = new RelayCommand(async () => await ExportReportAsync(), () => !IsGenerating && HasCollisions); CloseCommand = new RelayCommand(CloseWindow); - RefreshReportCommand = new RelayCommand(async () => await RefreshReportAsync(), () => !IsGenerating); HighlightCollisionCommand = new RelayCommand(HighlightCollision, item => item?.CollisionData != null); // 初始化状态 @@ -292,6 +327,12 @@ namespace NavisworksTransport.UI.WPF.ViewModels } } + // 设置动画参数 + PathName = reportResult.PathName; + FrameRate = reportResult.FrameRate; + Duration = reportResult.Duration; + DetectionGap = reportResult.DetectionGap; + // 更新统计信息 UpdateStatistics(reportResult); @@ -579,7 +620,8 @@ namespace NavisworksTransport.UI.WPF.ViewModels report.AppendLine("========================================"); report.AppendLine($"生成时间: {now:yyyy年MM月dd日 HH:mm:ss}"); report.AppendLine($"报告类型: {Statistics.ReportType}"); - + report.AppendLine($"路径名称: {PathName}"); + // 总体统计 report.AppendLine("=== 总体统计 ==="); report.AppendLine($"总碰撞数: {Statistics.TotalCollisions}"); @@ -587,13 +629,11 @@ namespace NavisworksTransport.UI.WPF.ViewModels report.AppendLine($"检测点: {Statistics.AnimationCollisions}个"); report.AppendLine(); - // 按状态分类 - report.AppendLine("=== 按状态分类 ==="); - report.AppendLine($"新发现: {Statistics.NewCollisions}"); - report.AppendLine($"活跃: {Statistics.ActiveCollisions}"); - report.AppendLine($"已审阅: {Statistics.ReviewedCollisions}"); - report.AppendLine($"已批准: {Statistics.ApprovedCollisions}"); - report.AppendLine($"已解决: {Statistics.ResolvedCollisions}"); + // 动画参数 + report.AppendLine("=== 动画参数 ==="); + report.AppendLine($"帧率: {FrameRate} FPS"); + report.AppendLine($"时长: {Duration:F1} 秒"); + report.AppendLine($"检测间隙: {DetectionGap:F2} 米"); report.AppendLine(); // 运动构件信息 @@ -686,8 +726,6 @@ namespace NavisworksTransport.UI.WPF.ViewModels html.AppendLine(".stat-item { background: white; padding: 15px; border-radius: 6px; border: 1px solid #ddd; text-align: center; }"); html.AppendLine(".stat-label { font-size: 12px; color: #666; margin-bottom: 5px; }"); html.AppendLine(".stat-value { font-size: 18px; font-weight: bold; color: #2c5aa0; }"); - html.AppendLine(".status-grid { display: grid; grid-template-columns: repeat(5, 1fr); gap: 10px; margin: 15px 0; }"); - html.AppendLine(".status-item { background: #f9f9f9; padding: 10px; border-radius: 4px; text-align: center; font-size: 12px; }"); html.AppendLine(".moving-object { background: #f0f8ff; padding: 15px; border-radius: 8px; text-align: center; margin: 15px 0; border: 1px solid #b0d4f1; }"); html.AppendLine(".collided-list { background: #f8fbff; padding: 15px; border-radius: 8px; margin: 15px 0; max-height: 200px; overflow-y: auto; }"); html.AppendLine(".list-item { margin: 5px 0; padding: 5px; border-left: 3px solid #2c5aa0; padding-left: 10px; }"); @@ -704,6 +742,7 @@ namespace NavisworksTransport.UI.WPF.ViewModels html.AppendLine($"

NavisworksTransport 碰撞检测报告

"); html.AppendLine($"

生成时间: {now:yyyy年MM月dd日 HH:mm:ss}

"); html.AppendLine($"

报告类型: {Statistics.ReportType}

"); + html.AppendLine($"

路径名称: {PathName}

"); // 总体统计 html.AppendLine("
"); @@ -724,14 +763,21 @@ namespace NavisworksTransport.UI.WPF.ViewModels html.AppendLine("
"); html.AppendLine(""); - // 状态分布 - html.AppendLine("

状态分布

"); - html.AppendLine("
"); - html.AppendLine($"
新发现
{Statistics.NewCollisions}
"); - html.AppendLine($"
活跃
{Statistics.ActiveCollisions}
"); - html.AppendLine($"
已审阅
{Statistics.ReviewedCollisions}
"); - html.AppendLine($"
已批准
{Statistics.ApprovedCollisions}
"); - html.AppendLine($"
已解决
{Statistics.ResolvedCollisions}
"); + // 动画参数 + html.AppendLine("

动画参数

"); + html.AppendLine("
"); + html.AppendLine("
"); + html.AppendLine("
帧率
"); + html.AppendLine($"
{FrameRate} FPS
"); + html.AppendLine("
"); + html.AppendLine("
"); + html.AppendLine("
时长
"); + html.AppendLine($"
{Duration:F1} 秒
"); + html.AppendLine("
"); + html.AppendLine("
"); + html.AppendLine("
检测间隙
"); + html.AppendLine($"
{DetectionGap:F2} 米
"); + html.AppendLine("
"); html.AppendLine("
"); // 运动构件信息 @@ -828,41 +874,6 @@ namespace NavisworksTransport.UI.WPF.ViewModels } } - /// - /// 刷新报告 - /// - private async Task RefreshReportAsync() - { - try - { - IsGenerating = true; - ProgressMessage = "正在重新生成报告..."; - ProgressPercentage = 0; - - // 重新执行碰撞报告生成 - var command = ViewCollisionReportCommand.CreateComprehensive(false); - var result = await command.ExecuteAsync(); - - if (result.IsSuccess && result is PathPlanningResult reportResult) - { - InitializeReport(reportResult.Data); - } - else - { - SetFailedReport(result.Message); - } - } - catch (Exception ex) - { - LogManager.Error($"刷新碰撞报告失败: {ex.Message}"); - SetFailedReport(ex.Message); - } - finally - { - IsGenerating = false; - } - } - /// /// 高亮碰撞对象 /// diff --git a/src/UI/WPF/ViewModels/PathEditingViewModel.cs b/src/UI/WPF/ViewModels/PathEditingViewModel.cs index 60a2aff..ce40470 100644 --- a/src/UI/WPF/ViewModels/PathEditingViewModel.cs +++ b/src/UI/WPF/ViewModels/PathEditingViewModel.cs @@ -667,6 +667,7 @@ namespace NavisworksTransport.UI.WPF.ViewModels // 创建对应的 WPF ViewModel var newPathViewModel = new PathRouteViewModel { + Id = newRoute.Id, // 添加Id属性设置 Name = newRoute.Name, Description = newRoute.Description, IsActive = true @@ -1834,6 +1835,7 @@ namespace NavisworksTransport.UI.WPF.ViewModels { var pathViewModel = new PathRouteViewModel { + Id = coreRoute.Id, // 添加Id属性设置 Name = coreRoute.Name, Description = coreRoute.Description, IsActive = false @@ -2540,6 +2542,7 @@ namespace NavisworksTransport.UI.WPF.ViewModels // 创建对应的 WPF ViewModel var autoPathViewModel = new PathRouteViewModel { + Id = e.Route.Id, Name = e.Route.Name, Description = e.Route.Description, IsActive = true @@ -2616,6 +2619,7 @@ namespace NavisworksTransport.UI.WPF.ViewModels // 创建对应的 WPF ViewModel var dbPathViewModel = new PathRouteViewModel { + Id = e.Route.Id, Name = e.Route.Name, Description = e.Route.Description, IsActive = false // 历史路径默认不激活 diff --git a/src/UI/WPF/Views/CollisionReportDialog.xaml b/src/UI/WPF/Views/CollisionReportDialog.xaml index 93074ea..2c37a82 100644 --- a/src/UI/WPF/Views/CollisionReportDialog.xaml +++ b/src/UI/WPF/Views/CollisionReportDialog.xaml @@ -224,37 +224,47 @@ NavisworksTransport 碰撞检测报告对话框 - 采用与主界面一致的Nav - -