From 075fd5c6021d6544e608caa0efcf016b68574112 Mon Sep 17 00:00:00 2001 From: tian <11429339@qq.com> Date: Fri, 9 Jan 2026 18:16:33 +0800 Subject: [PATCH] =?UTF-8?q?=E7=A7=BB=E9=99=A4=E9=A2=84=E8=AE=A1=E7=AE=97?= =?UTF-8?q?=E6=A3=80=E6=B5=8B=E9=97=B4=E9=9A=99=E6=89=A9=E5=A4=A7=E7=8E=87?= =?UTF-8?q?=E9=85=8D=E7=BD=AE=EF=BC=8C=E4=BC=98=E5=8C=96=E7=A2=B0=E6=92=9E?= =?UTF-8?q?=E6=A3=80=E6=B5=8B=E9=80=BB=E8=BE=91=E5=92=8C=E9=AB=98=E4=BA=AE?= =?UTF-8?q?=E6=98=BE=E7=A4=BA=E5=8A=9F=E8=83=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- default_config.toml | 4 -- doc/requirement/todo_features.md | 1 - .../GenerateCollisionReportCommand.cs | 3 +- src/Core/Animation/PathAnimationManager.cs | 49 ++++++++------ src/Core/Config/ConfigManager.cs | 2 - src/Core/Config/SystemConfig.cs | 5 -- src/Core/PathPlanningModels.cs | 3 +- .../ViewModels/AnimationControlViewModel.cs | 6 +- .../ViewModels/CollisionReportViewModel.cs | 3 +- src/Utils/BoundingBoxGeometryUtils.cs | 57 ----------------- src/Utils/ModelHighlightHelper.cs | 64 +++++-------------- 11 files changed, 52 insertions(+), 145 deletions(-) diff --git a/default_config.toml b/default_config.toml index 8435419..8b1d0e7 100644 --- a/default_config.toml +++ b/default_config.toml @@ -40,10 +40,6 @@ duration_seconds = 10.0 # 检测间隙(米) detection_gap_meters = 0.05 -# 预计算检测间隙扩大率(>0,表示扩大的倍数) -# 例如:0.5表示检测间隙增大0.5倍,即使用1.5倍的检测间隙进行预计算 -precomputed_detection_gap_expansion_rate = 0.5 - [logistics] # 可通行性(默认值:true) traversable = true diff --git a/doc/requirement/todo_features.md b/doc/requirement/todo_features.md index 9136683..7465a91 100644 --- a/doc/requirement/todo_features.md +++ b/doc/requirement/todo_features.md @@ -8,7 +8,6 @@ 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 d6117d4..226c7d8 100644 --- a/src/Commands/GenerateCollisionReportCommand.cs +++ b/src/Commands/GenerateCollisionReportCommand.cs @@ -218,8 +218,7 @@ namespace NavisworksTransport.Commands var highlightIntegration = ClashDetectiveIntegration.Instance; if (highlightIntegration != null) { - var highlightColor = Color.Green; // 绿色 (Navisworks API中没有Orange) - ModelHighlightHelper.HighlightCollisionResults(collisionData.AllCollisions, highlightColor, true); + ModelHighlightHelper.HighlightCollisionResults(collisionData.AllCollisions, clearPrevious: true); LogManager.Info($"自动高亮显示报告中的 {collisionData.AllCollisions.Count} 个碰撞对象"); } } diff --git a/src/Core/Animation/PathAnimationManager.cs b/src/Core/Animation/PathAnimationManager.cs index 059932a..102c3cd 100644 --- a/src/Core/Animation/PathAnimationManager.cs +++ b/src/Core/Animation/PathAnimationManager.cs @@ -190,10 +190,7 @@ namespace NavisworksTransport.Core.Animation var detectionGapMeters = config.Animation.DetectionGapMeters; _detectionGap = UnitsConverter.ConvertFromMeters(detectionGapMeters); - - var expansionRate = config.Animation.PrecomputedDetectionGapExpansionRate; - var expandedGapInMeters = detectionGapMeters * (1.0 + expansionRate); - _precomputedDetectionGap = UnitsConverter.ConvertFromMeters(expandedGapInMeters); + _precomputedDetectionGap = _detectionGap; // 初始化动画模式 _frameInterval = 1000.0 / _animationFrameRate; // 计算帧间隔 @@ -611,13 +608,16 @@ namespace NavisworksTransport.Core.Animation { var colliderBox = collider.BoundingBox(); - // 使用改进的精确距离检测方法(先检查相交,再计算精确距离) - double preciseDistance = BoundingBoxGeometryUtils.CalculatePreciseDistance(virtualBoundingBox, colliderBox); - bool intersects = preciseDistance <= _precomputedDetectionGap; + // 使用包围盒距离检测方法 + double distance = BoundingBoxGeometryUtils.CalculateDistance(virtualBoundingBox, colliderBox); + bool intersects = distance <= _precomputedDetectionGap; if (intersects) { - LogManager.Debug($"帧 {i} 检测到碰撞: {_animatedObject.DisplayName} <-> {collider.DisplayName}, 精确距离: {preciseDistance:F4},阈值: {_precomputedDetectionGap:F4}"); + LogManager.Debug($"帧 {i} 检测到碰撞: {_animatedObject.DisplayName} <-> {collider.DisplayName}, 距离: {distance:F4},阈值: {_precomputedDetectionGap:F4}"); + LogManager.Debug($"移动物体位置: {framePosition.X:F2},{framePosition.Y:F2},{framePosition.Z:F2}"); + LogManager.Debug($"被撞物体位置:{GetObjectPosition(collider).X:F2},{GetObjectPosition(collider).Y:F2},{GetObjectPosition(collider).Z:F2}"); + var collisionResult = new CollisionResult { ClashGuid = Guid.NewGuid(), @@ -955,6 +955,14 @@ namespace NavisworksTransport.Core.Animation ModelHighlightHelper.ClearCollisionHighlights(); LogManager.Debug("[动画开始] 已清除所有碰撞高亮"); + // 高亮车辆对象(绿色) + if (_animatedObject != null) + { + var vehicleItems = new List { _animatedObject }; + ModelHighlightHelper.HighlightItems(ModelHighlightHelper.AnimatedObjectCategory, vehicleItems); + LogManager.Debug("[动画开始] 已高亮车辆对象为绿色"); + } + // 启动动画播放 StartAnimationPlayback(); @@ -1073,6 +1081,10 @@ namespace NavisworksTransport.Core.Animation _pausedProgress = 0.0; // 重置暂停进度 _currentFrameIndex = 0; // 重置帧索引 + // 清除所有高亮(包括车辆和碰撞) + ModelHighlightHelper.ClearAllHighlights(); + LogManager.Info("动画停止:已清除所有高亮"); + // 将物体移回起点位置并恢复初始朝向 if (_pathPoints != null && _pathPoints.Count > 0 && _animatedObject != null) { @@ -1166,6 +1178,10 @@ namespace NavisworksTransport.Core.Animation // 直接设置为完成状态,避免中间状态切换 SetState(AnimationState.Finished); + // 清除所有高亮(包括车辆和碰撞) + ModelHighlightHelper.ClearAllHighlights(); + LogManager.Info("动画完成:已清除所有高亮"); + // 修复:显示正确的总帧数,而不是最后一帧的索引 var actualTotalFrames = _animationFrames?.Count ?? 0; LogManager.Info($"动画播放完成,总帧数: {actualTotalFrames}, 平均FPS: {_actualFPS:F1}"); @@ -2144,13 +2160,8 @@ 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})"); + // 预计算检测间隙与检测间隙相同 + _precomputedDetectionGap = _detectionGap; } } @@ -2316,15 +2327,15 @@ namespace NavisworksTransport.Core.Animation { if (currentHasCollision) { - // 有碰撞:高亮当前帧的碰撞对象 + // 有碰撞:高亮当前帧的碰撞对象(使用CollisionResultsCategory的默认颜色) ModelHighlightHelper.HighlightCollisionResults(currentFrame.Collisions); LogManager.Debug($"[高亮状态] 帧{_currentFrameIndex}: 高亮碰撞 ({currentFrame.Collisions.Count}个, 对象{currentCollisionObjects.Count}个)"); } else { - // 无碰撞:清除高亮 - ModelHighlightHelper.ClearCollisionHighlights(); - LogManager.Debug($"[高亮状态] 帧{_currentFrameIndex}: 清除高亮"); + // 无碰撞:清除碰撞高亮(保留车辆高亮) + ModelHighlightHelper.ClearCategory(ModelHighlightHelper.CollisionResultsCategory); + LogManager.Debug($"[高亮状态] 帧{_currentFrameIndex}: 清除碰撞高亮"); } // 更新状态记录 diff --git a/src/Core/Config/ConfigManager.cs b/src/Core/Config/ConfigManager.cs index 8be591f..3a151f8 100644 --- a/src/Core/Config/ConfigManager.cs +++ b/src/Core/Config/ConfigManager.cs @@ -198,7 +198,6 @@ 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")) @@ -345,7 +344,6 @@ 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 57ddd74..14b5080 100644 --- a/src/Core/Config/SystemConfig.cs +++ b/src/Core/Config/SystemConfig.cs @@ -127,11 +127,6 @@ namespace NavisworksTransport.Core.Config /// 检测间隙(米) /// public double DetectionGapMeters { get; set; } - - /// - /// 预计算检测间隙扩大率(>0,表示扩大的倍数) - /// - public double PrecomputedDetectionGapExpansionRate { get; set; } } /// diff --git a/src/Core/PathPlanningModels.cs b/src/Core/PathPlanningModels.cs index d4d6708..9202059 100644 --- a/src/Core/PathPlanningModels.cs +++ b/src/Core/PathPlanningModels.cs @@ -1397,8 +1397,7 @@ namespace NavisworksTransport if (selectedItems.Count > 0) { // 高亮显示选中的通道 - var navisColor = new Autodesk.Navisworks.Api.Color(0.0, 1.0, 0.0); // 绿色 - ModelHighlightHelper.HighlightItems(ChannelPreviewHighlightCategory, selectedItems, navisColor); + ModelHighlightHelper.HighlightItems(ChannelPreviewHighlightCategory, selectedItems); } } catch (Exception ex) diff --git a/src/UI/WPF/ViewModels/AnimationControlViewModel.cs b/src/UI/WPF/ViewModels/AnimationControlViewModel.cs index 7204d46..3abfde3 100644 --- a/src/UI/WPF/ViewModels/AnimationControlViewModel.cs +++ b/src/UI/WPF/ViewModels/AnimationControlViewModel.cs @@ -192,8 +192,6 @@ namespace NavisworksTransport.UI.WPF.ViewModels private const int ManualCollisionTargetLimit = 60; private const string ManualTargetsHighlightCategory = ModelHighlightHelper.ManualTargetsCategory; private const string CollisionResultsHighlightCategory = ModelHighlightHelper.CollisionResultsCategory; - private static readonly Color ManualTargetHighlightColor = Color.FromByteRGB(255, 170, 0); - private static readonly Color CollisionResultHighlightColor = Color.FromByteRGB(244, 67, 54); // Material Red(与路径终点颜色一致) #endregion @@ -1704,7 +1702,7 @@ namespace NavisworksTransport.UI.WPF.ViewModels LogManager.Debug($"[预计算碰撞结果高亮] 碰撞{i+1}: {collision.DisplayName}, Item1={collision.Item1?.DisplayName}, Item2={collision.Item2?.DisplayName}"); } - ModelHighlightHelper.HighlightCollisionResults(deduplicatedResults, CollisionResultHighlightColor, false); + ModelHighlightHelper.HighlightCollisionResults(deduplicatedResults, clearPrevious: false); UpdateMainStatus($"已高亮 {deduplicatedResults.Count} 个去重预计算碰撞结果"); LogManager.Info($"[预计算碰撞结果高亮] 已高亮 {deduplicatedResults.Count} 个结果"); } @@ -2003,7 +2001,7 @@ namespace NavisworksTransport.UI.WPF.ViewModels if (IsManualTargetModeActive || forceHighlight) { - ModelHighlightHelper.HighlightItems(ManualTargetsHighlightCategory, validItems, ManualTargetHighlightColor); + ModelHighlightHelper.HighlightItems(ManualTargetsHighlightCategory, validItems); } else { diff --git a/src/UI/WPF/ViewModels/CollisionReportViewModel.cs b/src/UI/WPF/ViewModels/CollisionReportViewModel.cs index b56c0a4..b848749 100644 --- a/src/UI/WPF/ViewModels/CollisionReportViewModel.cs +++ b/src/UI/WPF/ViewModels/CollisionReportViewModel.cs @@ -884,8 +884,7 @@ namespace NavisworksTransport.UI.WPF.ViewModels if (clashIntegration != null) { var collisions = new List { item.CollisionData }; - var highlightColor = Autodesk.Navisworks.Api.Color.Green; // 使用Navisworks API中可用的绿色 - ModelHighlightHelper.HighlightCollisionResults(collisions, highlightColor, true); + ModelHighlightHelper.HighlightCollisionResults(collisions, clearPrevious: true); LogManager.Info($"高亮碰撞对象: {item.Title}"); } } diff --git a/src/Utils/BoundingBoxGeometryUtils.cs b/src/Utils/BoundingBoxGeometryUtils.cs index c665ae6..ef73708 100644 --- a/src/Utils/BoundingBoxGeometryUtils.cs +++ b/src/Utils/BoundingBoxGeometryUtils.cs @@ -177,63 +177,6 @@ namespace NavisworksTransport.Utils box1.Min.Z <= box2.Max.Z && box1.Max.Z >= box2.Min.Z; } - /// - /// 使用ClosestPoint方法计算两个包围盒之间的精确距离 - /// 这种方法比简单的包围盒相交检测更精确,可以避免AABB扩大导致的误报 - /// - /// 第一个包围盒 - /// 第二个包围盒 - /// 两个包围盒之间的精确距离 - public static double CalculatePreciseDistance(BoundingBox3D box1, BoundingBox3D box2) - { - try - { - // 先检查包围盒是否相交 - bool intersects = box1.Intersects(box2); - - if (intersects) - { - return 0.0; - } - - // 如果不相交,使用ClosestPoint方法计算精确距离 - // 计算box1上距离box2最近的点 - Point3D closestPointOnBox1 = box1.ClosestPoint(box2.Center); - - // 计算box2上距离closestPointOnBox1最近的点 - Point3D closestPointOnBox2 = box2.ClosestPoint(closestPointOnBox1); - - // 计算两个最近点之间的距离 - double dx = closestPointOnBox1.X - closestPointOnBox2.X; - double dy = closestPointOnBox1.Y - closestPointOnBox2.Y; - double dz = closestPointOnBox1.Z - closestPointOnBox2.Z; - - double distance = Math.Sqrt(dx * dx + dy * dy + dz * dz); - return distance; - } - catch (Exception ex) - { - // API调用失败,记录错误并抛出异常 - LogManager.Error($"[CalculatePreciseDistance] API调用失败: {ex.Message}"); - throw new InvalidOperationException($"CalculatePreciseDistance API调用失败: {ex.Message}", ex); - } - } - - /// - /// 使用ClosestPoint方法检查两个包围盒是否在容差范围内相交 - /// 这种方法比简单的包围盒相交检测更精确,可以避免AABB扩大导致的误报 - /// - /// 第一个包围盒 - /// 第二个包围盒 - /// 容差值 - /// 如果包围盒在容差范围内相交则返回true - public static bool BoundingBoxesIntersectWithTolerancePrecise(BoundingBox3D box1, BoundingBox3D box2, double tolerance) - { - double preciseDistance = CalculatePreciseDistance(box1, box2); - return preciseDistance <= tolerance; - } - - /// /// 获取包围盒的中心点 /// diff --git a/src/Utils/ModelHighlightHelper.cs b/src/Utils/ModelHighlightHelper.cs index f69e801..b75f937 100644 --- a/src/Utils/ModelHighlightHelper.cs +++ b/src/Utils/ModelHighlightHelper.cs @@ -14,6 +14,7 @@ namespace NavisworksTransport.Utils public const string ManualTargetsCategory = "manualTargets"; public const string ChannelPreviewCategory = "channelPreview"; public const string ClashDetectiveResultsCategory = "clashDetectiveResults"; + public const string AnimatedObjectCategory = "animatedObject"; private class HighlightEntry { @@ -42,15 +43,16 @@ namespace NavisworksTransport.Utils { "report", Color.Green }, { "preview", Color.Blue }, { ManualTargetsCategory, Color.FromByteRGB(255, 170, 0) }, - { CollisionResultsCategory, Color.Green }, + { CollisionResultsCategory, Color.FromByteRGB(244, 67, 54) }, // Material Red(预计算碰撞) { ChannelPreviewCategory, Color.Green }, - { ClashDetectiveResultsCategory, Color.Red } + { ClashDetectiveResultsCategory, Color.Red }, + { AnimatedObjectCategory, Color.FromByteRGB(76, 175, 80) } // Material Green(动画车辆) }; /// - /// 高亮指定对象集合。 + /// 高亮指定对象集合(使用类别默认颜色)。 /// - public static void HighlightItems(string category, IEnumerable items, Color color) + public static void HighlightItems(string category, IEnumerable items) { if (items == null) return; @@ -64,6 +66,8 @@ namespace NavisworksTransport.Utils category = "default"; } + var color = GetCategoryColor(category); + lock (_syncRoot) { if (_activeHighlights.ContainsKey(category)) @@ -91,17 +95,6 @@ namespace NavisworksTransport.Utils } } - public static void HighlightItems(string category, IEnumerable items) - { - if (string.IsNullOrWhiteSpace(category)) - { - category = "default"; - } - - var color = GetCategoryColor(category); - HighlightItems(category, items, color); - } - /// /// 清除指定类别的高亮。 /// @@ -248,22 +241,11 @@ namespace NavisworksTransport.Utils #region 碰撞结果高亮相关方法 /// - /// 高亮显示碰撞对象(使用默认红色) + /// 高亮显示碰撞对象(使用类别默认颜色) /// /// 碰撞结果列表 /// 是否清除之前的高亮 public static void HighlightCollisionResults(List results, bool clearPrevious = true) - { - HighlightCollisionResults(results, Color.Red, clearPrevious); - } - - /// - /// 高亮显示碰撞对象(支持自定义颜色) - /// - /// 碰撞结果列表 - /// 高亮颜色 - /// 是否清除之前的高亮 - public static void HighlightCollisionResults(List results, Color highlightColor, bool clearPrevious = true) { try { @@ -289,18 +271,15 @@ namespace NavisworksTransport.Utils var item1 = collision.Item1; var item2 = collision.Item2; - if (item1 != null && !highlightItems.Contains(item1)) - { - highlightItems.Add(item1); - } - + // 只高亮被撞物体(Item2),排除车辆对象(Item1) + // 车辆对象由 AnimatedObjectCategory 单独高亮为绿色 if (item2 != null && !highlightItems.Contains(item2)) { highlightItems.Add(item2); } } - HighlightItems(CollisionResultsCategory, highlightItems, highlightColor); + HighlightItems(CollisionResultsCategory, highlightItems); } catch (Exception ex) { @@ -313,10 +292,9 @@ namespace NavisworksTransport.Utils /// /// 类别名称 /// 碰撞结果列表 - /// 高亮颜色 /// 是否清除其他类别 public static void ManageCollisionHighlightsByCategory(string category, List results, - Color highlightColor, bool clearOtherCategories = false) + bool clearOtherCategories = false) { try { @@ -329,11 +307,7 @@ namespace NavisworksTransport.Utils var item1 = result.Item1; var item2 = result.Item2; - if (item1 != null && !collidingItems.Contains(item1)) - { - collidingItems.Add(item1); - } - + // 只高亮被撞物体(Item2),排除车辆对象(Item1) if (item2 != null && !collidingItems.Contains(item2)) { collidingItems.Add(item2); @@ -346,7 +320,7 @@ namespace NavisworksTransport.Utils ClearCategory(category); } - HighlightItems(category, collidingItems, highlightColor); + HighlightItems(category, collidingItems); } catch (Exception ex) { @@ -382,11 +356,7 @@ namespace NavisworksTransport.Utils var highlightItems = new List(); foreach (var clash in clashResults) { - if (clash.Item1 != null && !highlightItems.Contains(clash.Item1)) - { - highlightItems.Add(clash.Item1); - } - + // 只高亮被撞物体(Item2),排除车辆对象(Item1) if (clash.Item2 != null && !highlightItems.Contains(clash.Item2)) { highlightItems.Add(clash.Item2); @@ -395,7 +365,7 @@ namespace NavisworksTransport.Utils if (highlightItems.Count > 0) { - HighlightItems(ClashDetectiveResultsCategory, highlightItems, Color.Red); + HighlightItems(ClashDetectiveResultsCategory, highlightItems); LogManager.Info($"[ClashDetective高亮] 已高亮 {highlightItems.Count} 个对象,来自 {clashResults.Count} 个碰撞结果"); } else