diff --git a/default_config.toml b/default_config.toml index 8b1d0e7..60c43ac 100644 --- a/default_config.toml +++ b/default_config.toml @@ -40,6 +40,10 @@ duration_seconds = 10.0 # 检测间隙(米) detection_gap_meters = 0.05 +# 预计算检测间隙扩大率(>0,表示扩大的倍数) +# 例如:1.0表示检测间隙增大1倍,即使用2倍的检测间隙进行预计算 +precomputed_detection_gap_expansion_rate = 1.0 + [logistics] # 可通行性(默认值:true) traversable = true diff --git a/doc/requirement/todo_features.md b/doc/requirement/todo_features.md index 7465a91..9136683 100644 --- a/doc/requirement/todo_features.md +++ b/doc/requirement/todo_features.md @@ -8,6 +8,7 @@ 2. [x] (BUG)碰撞结果高亮,应该显示clashdetective检测的结果 3. [x] (优化)对clashdetective的检测结果,进行向上合并,找到集合对象。 4. [x] (功能)碰撞检测结果保存数据库,列表展示 +5. [x] (优化)系统设置中增加预计算检测间隙扩大率,扩大预计算碰撞检测范围。 ### [2025/12/25] diff --git a/src/Commands/GenerateCollisionReportCommand.cs b/src/Commands/GenerateCollisionReportCommand.cs index e8e87f8..d6117d4 100644 --- a/src/Commands/GenerateCollisionReportCommand.cs +++ b/src/Commands/GenerateCollisionReportCommand.cs @@ -82,10 +82,10 @@ namespace NavisworksTransport.Commands 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; + public string PathName { get; set; } + public int FrameRate { get; set; } + public double Duration { get; set; } + public double DetectionGap { get; set; } } /// diff --git a/src/Core/Animation/PathAnimationManager.cs b/src/Core/Animation/PathAnimationManager.cs index 07fedfa..dfb8666 100644 --- a/src/Core/Animation/PathAnimationManager.cs +++ b/src/Core/Animation/PathAnimationManager.cs @@ -115,7 +115,7 @@ namespace NavisworksTransport.Core.Animation private PathRoute _route = null; // 路径引用 // === 碰撞测试优化 === - private string _currentAnimationHash = ""; // 当前动画配置的哈希值 + private string _currentAnimationHash; // 当前动画配置的哈希值 // === 动画播放机制 === private double _frameInterval; // 帧间隔(毫秒) @@ -123,16 +123,15 @@ namespace NavisworksTransport.Core.Animation private DispatcherTimer _animationTimer; // 备用DispatcherTimer定时器 // === 动画参数 === - private double _animationDuration = 10.0; // 动画总时长(秒) + private double _animationDuration; // 动画总时长(秒) private DateTime _animationStartTime; - private int _animationFrameRate = 30; // 动画帧率(默认30FPS) - private int _animationFrameCount = 0; // 动画帧计数 - private double _collisionDetectionAccuracy = 0.1; // 检测精度(内部存储:模型单位/帧) - private double _movementSpeed = 1.0; // 运动速度(仅用于显示,单位:米/秒) - private double _detectionGap = 0.05; // 检测间隙(内部存储:模型单位) - private string _pathName = "未知路径"; // 路径名称 - private string _currentRouteId = null; // 当前路由ID - private string _animatedObjectName = null; // 动画对象名称 + private int _animationFrameRate; // 动画帧率(默认30FPS) + private double _collisionDetectionAccuracy; // 检测精度(内部存储:模型单位/帧) + private double _movementSpeed; // 运动速度(仅用于显示,单位:米/秒) + private double _detectionGap; // 检测间隙(内部存储:模型单位) + private double _precomputedDetectionGap; // 预计算时使用的扩大检测间隙(内部存储:模型单位) + private string _pathName; // 路径名称 + private string _currentRouteId; // 当前路由ID // === 双向播放和步进控制 === private int _playbackDirection = 1; // 播放方向:1=正向,-1=反向 @@ -184,6 +183,18 @@ namespace NavisworksTransport.Core.Animation _animationFrames = new List(); _allCollisionResults = new List(); + // 🔥 从配置初始化动画参数 + var config = ConfigManager.Instance.Current; + _animationFrameRate = config.Animation.FrameRate; + _animationDuration = config.Animation.DurationSeconds; + + var detectionGapMeters = config.Animation.DetectionGapMeters; + _detectionGap = UnitsConverter.ConvertFromMeters(detectionGapMeters); + + var expansionRate = config.Animation.PrecomputedDetectionGapExpansionRate; + var expandedGapInMeters = detectionGapMeters * (1.0 + expansionRate); + _precomputedDetectionGap = UnitsConverter.ConvertFromMeters(expandedGapInMeters); + // 初始化动画模式 _frameInterval = 1000.0 / _animationFrameRate; // 计算帧间隔 _lastFrameTime = DateTime.MinValue; @@ -506,7 +517,7 @@ namespace NavisworksTransport.Core.Animation // 原因:车辆在通道上水平移动,主要检测侧面碰撞 double maxHorizontalDimension = Math.Max(boundingBoxSize.X, boundingBoxSize.Y); - searchRadiusInModelUnits = maxHorizontalDimension + _detectionGap; + searchRadiusInModelUnits = maxHorizontalDimension + _precomputedDetectionGap; LogManager.Info($"空间查询半径: {searchRadiusInModelUnits:F2} 模型单位 (基于最大水平尺寸: {maxHorizontalDimension:F2})"); } @@ -602,7 +613,7 @@ namespace NavisworksTransport.Core.Animation // 使用改进的精确距离检测方法(先检查相交,再计算精确距离) double preciseDistance = BoundingBoxGeometryUtils.CalculatePreciseDistance(virtualBoundingBox, colliderBox); - bool intersects = preciseDistance <= _detectionGap; + bool intersects = preciseDistance <= _precomputedDetectionGap; if (intersects) { @@ -911,7 +922,6 @@ namespace NavisworksTransport.Core.Animation // 初始化动画状态 _animationStartTime = DateTime.Now; - _animationFrameCount = 0; // 重置帧计数 _currentFrameIndex = 0; // 重置当前帧索引,确保从第一帧开始 _pausedProgress = 0.0; // 重置暂停进度 @@ -2132,6 +2142,14 @@ namespace NavisworksTransport.Core.Animation { _detectionGap = roundedGapInModelUnits; LogManager.Info($"检测间隙设置为: {gapInMeters:F2}米"); + + // 计算预计算时使用的扩大检测间隙 + var config = ConfigManager.Instance.Current; + var expansionRate = config?.Animation?.PrecomputedDetectionGapExpansionRate ?? 0.0; + var expandedGapInMeters = gapInMeters * (1.0 + expansionRate); + var expandedGapInModelUnits = UnitsConverter.ConvertFromMeters(expandedGapInMeters); + _precomputedDetectionGap = Math.Round(expandedGapInModelUnits, 4); + LogManager.Info($"预计算检测间隙设置为: {expandedGapInMeters:F2}米(扩大率: {expansionRate:F2})"); } } @@ -2407,7 +2425,6 @@ namespace NavisworksTransport.Core.Animation // 记录帧时间和统计 _lastFrameTime = now; - _animationFrameCount++; // 性能监控和自动切换 UpdateFPSCounterAndCheckSwitch(); diff --git a/src/Core/Collision/ClashDetectiveIntegration.cs b/src/Core/Collision/ClashDetectiveIntegration.cs index e7c264c..d58ea4f 100644 --- a/src/Core/Collision/ClashDetectiveIntegration.cs +++ b/src/Core/Collision/ClashDetectiveIntegration.cs @@ -540,7 +540,7 @@ namespace NavisworksTransport /// 虚拟车辆长度(米) /// 虚拟车辆宽度(米) /// 虚拟车辆高度(米) - public void CreateAllAnimationCollisionTests(List precomputedCollisions, double detectionGap = 0.05, + public void CreateAllAnimationCollisionTests(List precomputedCollisions, double detectionGap, string pathName = "未知路径", string routeId = null, ModelItem animatedObject = null, bool isVirtualVehicle = false, int frameRate = 30, double duration = 10.0, diff --git a/src/Core/Config/ConfigManager.cs b/src/Core/Config/ConfigManager.cs index 3a151f8..8be591f 100644 --- a/src/Core/Config/ConfigManager.cs +++ b/src/Core/Config/ConfigManager.cs @@ -198,6 +198,7 @@ namespace NavisworksTransport.Core.Config config.Animation.FrameRate = GetRequiredIntValue(anim, "frame_rate"); config.Animation.DurationSeconds = GetRequiredDoubleValue(anim, "duration_seconds"); config.Animation.DetectionGapMeters = GetRequiredDoubleValue(anim, "detection_gap_meters"); + config.Animation.PrecomputedDetectionGapExpansionRate = GetRequiredDoubleValue(anim, "precomputed_detection_gap_expansion_rate"); // 加载物流属性配置 if (!model.ContainsKey("logistics")) @@ -344,6 +345,7 @@ namespace NavisworksTransport.Core.Config anim["frame_rate"] = config.Animation.FrameRate; anim["duration_seconds"] = config.Animation.DurationSeconds; anim["detection_gap_meters"] = config.Animation.DetectionGapMeters; + anim["precomputed_detection_gap_expansion_rate"] = config.Animation.PrecomputedDetectionGapExpansionRate; } } diff --git a/src/Core/Config/SystemConfig.cs b/src/Core/Config/SystemConfig.cs index 14b5080..57ddd74 100644 --- a/src/Core/Config/SystemConfig.cs +++ b/src/Core/Config/SystemConfig.cs @@ -127,6 +127,11 @@ namespace NavisworksTransport.Core.Config /// 检测间隙(米) /// public double DetectionGapMeters { get; set; } + + /// + /// 预计算检测间隙扩大率(>0,表示扩大的倍数) + /// + public double PrecomputedDetectionGapExpansionRate { get; set; } } /// diff --git a/src/Core/MainPlugin.cs b/src/Core/MainPlugin.cs index eac9c24..ef8820a 100644 --- a/src/Core/MainPlugin.cs +++ b/src/Core/MainPlugin.cs @@ -334,6 +334,17 @@ namespace NavisworksTransport LogManager.Info("[文档管理] 插件OnLoaded - 开始初始化"); + //显式初始化配置管理器,确保配置加载完成 + try + { + var config = NavisworksTransport.Core.Config.ConfigManager.Instance.Current; + LogManager.Info($"[配置管理] 配置已加载"); + } + catch (Exception ex) + { + LogManager.Error($"[配置管理] 配置加载失败: {ex.Message}"); + } + // 订阅文档事件 SubscribeToDocumentEvents(); diff --git a/src/PathPlanning/PathOptimizer.cs b/src/PathPlanning/PathOptimizer.cs index ef8f55e..0aaafda 100644 --- a/src/PathPlanning/PathOptimizer.cs +++ b/src/PathPlanning/PathOptimizer.cs @@ -24,37 +24,37 @@ namespace NavisworksTransport.PathPlanning /// /// 共线检测的容差值(米) /// - public double CollinearTolerance { get; set; } = 0.01; + public double CollinearTolerance { get; set; } /// /// 是否启用路径平滑(未来扩展) /// - public bool EnableSmoothing { get; set; } = false; + public bool EnableSmoothing { get; set; } /// /// 转弯半径(米,未来扩展) /// - public double TurningRadius { get; set; } = 1.0; + public double TurningRadius { get; set; } /// /// 圆弧分段数(未来扩展) /// - public int ArcSegments { get; set; } = 8; + public int ArcSegments { get; set; } /// /// 是否启用碰撞检测验证(未来扩展) /// - public bool EnableCollisionCheck { get; set; } = false; + public bool EnableCollisionCheck { get; set; } /// /// 车辆长度(米,未来扩展) /// - public double VehicleLength { get; set; } = 2.0; + public double VehicleLength { get; set; } /// /// 车辆宽度(米,未来扩展) /// - public double VehicleWidth { get; set; } = 1.0; + public double VehicleWidth { get; set; } } private readonly OptimizationConfig _config; diff --git a/src/UI/WPF/ViewModels/AnimationControlViewModel.cs b/src/UI/WPF/ViewModels/AnimationControlViewModel.cs index 9d31934..7204d46 100644 --- a/src/UI/WPF/ViewModels/AnimationControlViewModel.cs +++ b/src/UI/WPF/ViewModels/AnimationControlViewModel.cs @@ -174,16 +174,15 @@ namespace NavisworksTransport.UI.WPF.ViewModels // 移动物体相关字段 private ModelItem _selectedAnimatedObject; - private string _selectedAnimatedObjectName = "未选择移动物体"; + private string _selectedAnimatedObjectName; private bool _hasSelectedAnimatedObject = false; private bool _canGenerateAnimation = false; // 虚拟车辆相关字段 - private bool _useSelectedObject = true; // 默认使用选择物体方式 private bool _useVirtualVehicle = false; // 使用虚拟车辆 - private double _virtualVehicleLength = 1.0; // 虚拟车辆长度(米) - private double _virtualVehicleWidth = 1.0; // 虚拟车辆宽度(米) - private double _virtualVehicleHeight = 2.0; // 虚拟车辆高度(米) + private double _virtualVehicleLength; // 虚拟车辆长度(米) + private double _virtualVehicleWidth; // 虚拟车辆宽度(米) + private double _virtualVehicleHeight; // 虚拟车辆高度(米) // 手工碰撞对象相关字段 private bool _isManualCollisionTargetEnabled = false; @@ -459,35 +458,6 @@ namespace NavisworksTransport.UI.WPF.ViewModels /// /// 是否使用选择的模型物体 /// - public bool UseSelectedObject - { - get => _useSelectedObject; - set - { - if (SetProperty(ref _useSelectedObject, value)) - { - if (value) - { - _useVirtualVehicle = false; - OnPropertyChanged(nameof(UseVirtualVehicle)); - - // ✨ 模式切换清理:切换到手动选择模式时,移除存在的虚拟车辆并清理数据 - try - { - VirtualVehicleManager.Instance.RemoveVirtualVehicle(); - _pathAnimationManager?.ClearAnimationResults(); // 清理虚拟车辆留下的动画数据 - LogManager.Info("已切换到手动选择模式,自动隐藏虚拟车辆并清理动画数据"); - } - catch (Exception ex) - { - LogManager.Warning($"隐藏虚拟车辆失败: {ex.Message}"); - } - } - UpdateCanGenerateAnimation(); - } - } - } - /// /// 是否使用虚拟车辆 /// @@ -498,12 +468,9 @@ namespace NavisworksTransport.UI.WPF.ViewModels { if (SetProperty(ref _useVirtualVehicle, value)) { + // ✨ 模式切换清理:切换到虚拟车辆模式时,移除选择物体的动画数据 if (value) { - _useSelectedObject = false; - OnPropertyChanged(nameof(UseSelectedObject)); - - // ✨ 模式切换清理:切换到虚拟车辆模式时,重置之前手动选择物体的动画状态(恢复到CAD位置) try { // 只有在当前动画对象不是虚拟车辆时才执行重置 @@ -532,7 +499,21 @@ namespace NavisworksTransport.UI.WPF.ViewModels } catch (Exception ex) { - LogManager.Warning($"重置手动选择物体状态失败: {ex.Message}"); + LogManager.Warning($"切换到虚拟车辆模式失败: {ex.Message}"); + } + } + else + { + // ✨ 模式切换清理:切换到手动选择模式时,移除存在的虚拟车辆并清理数据 + try + { + VirtualVehicleManager.Instance.RemoveVirtualVehicle(); + _pathAnimationManager?.ClearAnimationResults(); // 清理虚拟车辆留下的动画数据 + LogManager.Info("已切换到手动选择模式,自动隐藏虚拟车辆并清理动画数据"); + } + catch (Exception ex) + { + LogManager.Warning($"隐藏虚拟车辆失败: {ex.Message}"); } } UpdateCanGenerateAnimation(); @@ -823,6 +804,11 @@ namespace NavisworksTransport.UI.WPF.ViewModels DetectionGap = config.Animation.DetectionGapMeters; AnimationFrameRate = config.Animation.FrameRate; + // 🔥 从配置加载虚拟车辆尺寸(与路径编辑保持一致) + VirtualVehicleLength = config.PathEditing.VehicleLengthMeters; + VirtualVehicleWidth = config.PathEditing.VehicleWidthMeters; + VirtualVehicleHeight = config.PathEditing.VehicleHeightMeters; + // 设置动画按钮的初始状态 UpdateAnimationButtonStates(); diff --git a/src/UI/WPF/Views/AnimationControlView.xaml b/src/UI/WPF/Views/AnimationControlView.xaml index 9688a31..49f966d 100644 --- a/src/UI/WPF/Views/AnimationControlView.xaml +++ b/src/UI/WPF/Views/AnimationControlView.xaml @@ -238,7 +238,6 @@ NavisworksTransport 检测动画页签视图 - 采用与类别设置和分层管 + Visibility="{Binding UseVirtualVehicle, Converter={StaticResource BoolToVisConverter}, ConverterParameter=Inverse}">