修改Clashdetective进度条不展示百分比,以及不能取消的问题;进度条关闭主窗口失焦问题
This commit is contained in:
parent
3138b73a5f
commit
a9ccc057d3
@ -4218,3 +4218,220 @@ public static class ViewpointHelper
|
||||
**文档版本**:2026.2
|
||||
**最后更新**:基于 ViewpointHelper 重构经验(聚焦功能实现)
|
||||
**适用版本**:Navisworks Manage 2026
|
||||
|
||||
|
||||
## 15. Progress 进度条与窗口焦点管理 ⚠️ 重要
|
||||
|
||||
### 15.1 问题现象
|
||||
|
||||
在使用 `Application.BeginProgress` 创建进度条后,如果在 `finally` 块中关闭进度条并立即显示消息对话框,会出现以下问题:
|
||||
|
||||
1. **焦点丢失**:关闭进度条后,Navisworks 主窗口失去焦点,Windows 将焦点交给其他应用程序
|
||||
2. **消息框被遮盖**:消息对话框显示在其他应用程序后面,用户需要点击任务栏才能看到
|
||||
3. **用户体验差**:用户以为程序卡死或无响应
|
||||
|
||||
### 15.2 根本原因
|
||||
|
||||
Navisworks 的 `Progress` 是一个**应用程序级别的模态对话框**:
|
||||
|
||||
```
|
||||
进度条关闭时:
|
||||
1. Windows 焦点管理器需要决定下一个获得焦点的窗口
|
||||
2. 如果 Navisworks 主窗口之前被进度条遮盖/禁用
|
||||
3. 关闭后焦点可能没有正确回到主窗口
|
||||
4. Windows 可能将焦点交给其他应用程序(如资源管理器、浏览器等)
|
||||
```
|
||||
|
||||
### 15.3 错误做法
|
||||
|
||||
```csharp
|
||||
// ❌ 错误:先关闭进度条,后显示消息框
|
||||
try
|
||||
{
|
||||
// 执行长时间操作...
|
||||
ShowMessage("操作完成"); // 先显示消息
|
||||
}
|
||||
finally
|
||||
{
|
||||
Application.EndProgress(); // 后关闭进度条
|
||||
}
|
||||
// 结果:消息框显示在进度条后面,进度条关闭时焦点丢失
|
||||
```
|
||||
|
||||
### 15.4 正确做法
|
||||
|
||||
**解决方案:在关闭进度条之前,先显式激活 Navisworks 主窗口**
|
||||
|
||||
```csharp
|
||||
// ✅ 正确:先激活主窗口,再关闭进度条,最后显示消息框
|
||||
using System.Runtime.InteropServices;
|
||||
|
||||
public class ClashDetectiveIntegration
|
||||
{
|
||||
// Windows API: 设置前台窗口
|
||||
[DllImport("user32.dll")]
|
||||
private static extern bool SetForegroundWindow(IntPtr hWnd);
|
||||
|
||||
public void LongRunningOperation()
|
||||
{
|
||||
Progress progress = Application.BeginProgress("正在处理...", "请稍候");
|
||||
|
||||
try
|
||||
{
|
||||
// 执行长时间操作...
|
||||
RunCollisionDetection(progress);
|
||||
}
|
||||
finally
|
||||
{
|
||||
// 🔥 关键:先激活 Navisworks 主窗口
|
||||
try
|
||||
{
|
||||
var mainWindow = Autodesk.Navisworks.Api.Application.Gui.MainWindow;
|
||||
if (mainWindow != null)
|
||||
{
|
||||
SetForegroundWindow(mainWindow.Handle);
|
||||
}
|
||||
}
|
||||
catch { /* 忽略激活失败 */ }
|
||||
|
||||
// 然后关闭进度条
|
||||
Application.EndProgress();
|
||||
}
|
||||
|
||||
// 最后显示消息对话框(在主窗口激活后)
|
||||
ShowCancellationMessage();
|
||||
}
|
||||
|
||||
private void ShowCancellationMessage()
|
||||
{
|
||||
// 使用主窗口作为父窗口
|
||||
var mainWindow = System.Windows.Forms.Form.FromHandle(
|
||||
Autodesk.Navisworks.Api.Application.Gui.MainWindow.Handle);
|
||||
|
||||
System.Windows.Forms.MessageBox.Show(
|
||||
mainWindow, // 指定父窗口
|
||||
"操作已取消。",
|
||||
"取消",
|
||||
System.Windows.Forms.MessageBoxButtons.OK,
|
||||
System.Windows.Forms.MessageBoxIcon.Information);
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### 15.5 实际应用案例
|
||||
|
||||
**场景:碰撞检测取消后的处理**
|
||||
|
||||
```csharp
|
||||
public bool CreateAllAnimationCollisionTests(...)
|
||||
{
|
||||
// 重置取消标志
|
||||
_wasLastTestCanceled = false;
|
||||
|
||||
Progress progress = Application.BeginProgress("碰撞检测数据分析中,请稍候...");
|
||||
bool wasCanceled = false;
|
||||
|
||||
try
|
||||
{
|
||||
var result = RunClashDetectiveTestsAndSaveToDatabase(..., progress);
|
||||
wasCanceled = result.wasCanceled;
|
||||
|
||||
if (wasCanceled)
|
||||
{
|
||||
// 设置取消标志
|
||||
_wasLastTestCanceled = true;
|
||||
|
||||
// 清空结果
|
||||
ClearCurrentTestCache();
|
||||
|
||||
// 恢复物体状态
|
||||
PathAnimationManager.GetInstance().RestoreAnimatedObjectState(animatedObject);
|
||||
|
||||
// 重置动画完成标志
|
||||
ResetAnimationCompletedFlag(routeId);
|
||||
}
|
||||
}
|
||||
finally
|
||||
{
|
||||
// 🔥 关键:先激活 Navisworks 主窗口(避免关闭进度条后丢失焦点)
|
||||
try
|
||||
{
|
||||
var mainWindow = Autodesk.Navisworks.Api.Application.Gui.MainWindow;
|
||||
if (mainWindow != null)
|
||||
{
|
||||
SetForegroundWindow(mainWindow.Handle);
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
LogManager.Debug($"[ClashDetective] 激活主窗口失败: {ex.Message}");
|
||||
}
|
||||
|
||||
// 关闭进度条
|
||||
Application.EndProgress();
|
||||
}
|
||||
|
||||
// 如果取消,在 finally 之后显示提示消息
|
||||
if (wasCanceled)
|
||||
{
|
||||
ShowCancellationMessage();
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
```
|
||||
|
||||
### 15.6 关键要点总结
|
||||
|
||||
| 步骤 | 操作 | 目的 |
|
||||
|------|------|------|
|
||||
| 1 | `SetForegroundWindow(mainWindow.Handle)` | 显式激活 Navisworks 主窗口 |
|
||||
| 2 | `Application.EndProgress()` | 关闭进度条 |
|
||||
| 3 | `MessageBox.Show(mainWindow, ...)` | 显示消息对话框(使用父窗口) |
|
||||
|
||||
**为什么这个顺序有效?**
|
||||
|
||||
1. **激活主窗口**:在进度条关闭前,先让主窗口成为活动窗口
|
||||
2. **关闭进度条**:进度条关闭时,焦点会回到已经激活的主窗口
|
||||
3. **显示消息框**:消息框作为主窗口的子窗口,自然显示在最前面
|
||||
|
||||
### 15.7 常见错误
|
||||
|
||||
```csharp
|
||||
// ❌ 错误1:先显示消息框,后关闭进度条
|
||||
try { }
|
||||
finally
|
||||
{
|
||||
ShowMessage("完成"); // 消息框在进度条前显示
|
||||
Application.EndProgress(); // 关闭进度条时消息框也消失
|
||||
}
|
||||
|
||||
// ❌ 错误2:只关闭进度条,不激活主窗口
|
||||
try { }
|
||||
finally
|
||||
{
|
||||
Application.EndProgress(); // 焦点丢失
|
||||
}
|
||||
ShowMessage("完成"); // 消息框显示在其他程序后面
|
||||
|
||||
// ❌ 错误3:使用延时等待
|
||||
finally
|
||||
{
|
||||
Application.EndProgress();
|
||||
Thread.Sleep(100); // 不必要的延时
|
||||
Application.DoEvents();
|
||||
}
|
||||
```
|
||||
|
||||
### 15.8 最佳实践
|
||||
|
||||
1. **始终使用 `SetForegroundWindow`** 在关闭进度条前激活主窗口
|
||||
2. **指定父窗口** 在 `MessageBox.Show` 中使用 `mainWindow` 参数
|
||||
3. **正确处理异常** 激活失败不应影响主要功能
|
||||
4. **保持代码简洁** 不需要 Thread.Sleep 等延时操作
|
||||
5. **测试验证** 在取消操作后验证焦点是否正确回到 Navisworks
|
||||
|
||||
---
|
||||
|
||||
*最后更新:2026-02-14 - 添加了 Progress 进度条焦点管理的实践经验*
|
||||
|
||||
@ -1681,10 +1681,11 @@ namespace NavisworksTransport.Core.Animation
|
||||
var oldCursor = System.Windows.Input.Mouse.OverrideCursor;
|
||||
System.Windows.Input.Mouse.OverrideCursor = System.Windows.Input.Cursors.Wait;
|
||||
|
||||
bool testCompleted = false;
|
||||
try
|
||||
{
|
||||
// 🔥 使用用户设置的检测容差(米)
|
||||
ClashDetectiveIntegration.Instance.CreateAllAnimationCollisionTests(
|
||||
testCompleted = ClashDetectiveIntegration.Instance.CreateAllAnimationCollisionTests(
|
||||
_allCollisionResults,
|
||||
_detectionTolerance,
|
||||
_currentRouteId,
|
||||
@ -1704,8 +1705,16 @@ namespace NavisworksTransport.Core.Animation
|
||||
System.Windows.Input.Mouse.OverrideCursor = oldCursor;
|
||||
}
|
||||
|
||||
_completedCollisionTests.Add(_currentAnimationHash); // 记录此配置已完成碰撞检测
|
||||
LogManager.Info($"碰撞测试汇总已创建并记录,此配置后续播放将跳过碰撞检测");
|
||||
// 只有在检测成功完成(未被取消)的情况下才记录为已完成
|
||||
if (testCompleted)
|
||||
{
|
||||
_completedCollisionTests.Add(_currentAnimationHash); // 记录此配置已完成碰撞检测
|
||||
LogManager.Info($"碰撞测试汇总已创建并记录,此配置后续播放将跳过碰撞检测");
|
||||
}
|
||||
else
|
||||
{
|
||||
LogManager.Info("碰撞检测被取消,不记录为已完成,允许下次重新检测");
|
||||
}
|
||||
}
|
||||
else if (_completedCollisionTests.Contains(_currentAnimationHash))
|
||||
{
|
||||
|
||||
@ -1,6 +1,7 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Runtime.InteropServices;
|
||||
using Autodesk.Navisworks.Api;
|
||||
using Autodesk.Navisworks.Api.Clash;
|
||||
using NavisworksTransport.Core;
|
||||
@ -15,6 +16,10 @@ namespace NavisworksTransport
|
||||
/// </summary>
|
||||
public class ClashDetectiveIntegration
|
||||
{
|
||||
// Windows API: 设置前台窗口
|
||||
[DllImport("user32.dll")]
|
||||
private static extern bool SetForegroundWindow(IntPtr hWnd);
|
||||
|
||||
private static ClashDetectiveIntegration _instance;
|
||||
|
||||
private DocumentClash _documentClash;
|
||||
@ -71,6 +76,17 @@ namespace NavisworksTransport
|
||||
|
||||
private string _currentTestName;
|
||||
|
||||
// 🔥 检测取消标志
|
||||
private bool _wasLastTestCanceled = false;
|
||||
|
||||
/// <summary>
|
||||
/// 上次检测是否被取消
|
||||
/// </summary>
|
||||
public bool WasLastTestCanceled
|
||||
{
|
||||
get { return _wasLastTestCanceled; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 单例实例
|
||||
/// </summary>
|
||||
@ -663,8 +679,8 @@ namespace NavisworksTransport
|
||||
/// <summary>
|
||||
/// 运行ClashDetective测试并保存到数据库(公共方法,供批处理和非批处理调用)
|
||||
/// </summary>
|
||||
/// <returns>碰撞分组、主测试、确认的碰撞数量</returns>
|
||||
public (ClashResultGroup collisionGroup, ClashTest addedMainTest, int confirmedCount) RunClashDetectiveTestsAndSaveToDatabase(
|
||||
/// <returns>碰撞分组、主测试、确认的碰撞数量、是否被取消</returns>
|
||||
public (ClashResultGroup collisionGroup, ClashTest addedMainTest, int confirmedCount, bool wasCanceled) RunClashDetectiveTestsAndSaveToDatabase(
|
||||
List<CollisionResult> precomputedCollisions,
|
||||
double detectionGap,
|
||||
string routeId,
|
||||
@ -719,7 +735,7 @@ namespace NavisworksTransport
|
||||
if (addedMainTest == null)
|
||||
{
|
||||
LogManager.Error("[分组测试] 无法获取添加后的主测试对象");
|
||||
return (null, null, 0);
|
||||
return (null, null, 0, false);
|
||||
}
|
||||
|
||||
// 如果没有有效碰撞,直接保存空记录并返回
|
||||
@ -745,7 +761,7 @@ namespace NavisworksTransport
|
||||
precomputedCollisionCount
|
||||
);
|
||||
|
||||
return (null, addedMainTest, 0);
|
||||
return (null, addedMainTest, 0, false);
|
||||
}
|
||||
|
||||
// 第二步:创建分组并添加碰撞结果(应用智能去重)
|
||||
@ -781,11 +797,17 @@ namespace NavisworksTransport
|
||||
int skippedCount = 0;
|
||||
int testCount = 0; // 检测计数器,用于进度日志
|
||||
int totalTests = validCollisions.Count; // 总检测次数(预估)
|
||||
int totalGroups = groupedCollisions.Count; // 总组数
|
||||
var doc = Application.ActiveDocument;
|
||||
|
||||
// 初始化进度条
|
||||
progress?.Update(0.0);
|
||||
|
||||
// 收集所有临时测试,用于批量删除
|
||||
var tempTestsToRemove = new List<ClashTest>();
|
||||
|
||||
bool wasCanceled = false;
|
||||
|
||||
// 2. 遍历每一组
|
||||
for (int groupIndex = 0; groupIndex < groupedCollisions.Count; groupIndex++)
|
||||
{
|
||||
@ -793,9 +815,17 @@ namespace NavisworksTransport
|
||||
if (progress != null && progress.IsCanceled)
|
||||
{
|
||||
LogManager.Info($"[分组测试] 用户取消操作,已处理 {groupIndex}/{groupedCollisions.Count} 组");
|
||||
wasCanceled = true;
|
||||
break;
|
||||
}
|
||||
|
||||
// 更新进度条(每5组更新一次,避免过于频繁)
|
||||
if (groupIndex % 5 == 0 || groupIndex == groupedCollisions.Count - 1)
|
||||
{
|
||||
double progressPercent = (double)groupIndex / totalGroups * 0.7; // 组进度占70%
|
||||
progress?.Update(progressPercent);
|
||||
}
|
||||
|
||||
var group = groupedCollisions[groupIndex];
|
||||
|
||||
// 3. 排序:按距离/重叠深度排序,优先检测最严重的碰撞
|
||||
@ -898,12 +928,20 @@ namespace NavisworksTransport
|
||||
|
||||
_documentClash.TestsData.TestsRunTest(addedTempTest);
|
||||
|
||||
// 增加检测计数并打印进度日志(每100次)
|
||||
// 增加检测计数并打印进度日志(每50次更新一次进度条,每100次打印日志)
|
||||
testCount++;
|
||||
if (testCount % 50 == 0)
|
||||
{
|
||||
// 基于总检测次数计算进度(组进度占70%,检测进度占30%)
|
||||
double groupProgress = (double)(groupIndex + 1) / totalGroups * 0.7;
|
||||
double testProgress = (double)testCount / totalTests * 0.3;
|
||||
double totalProgress = Math.Min(groupProgress + testProgress, 0.99);
|
||||
progress?.Update(totalProgress);
|
||||
}
|
||||
if (testCount % 100 == 0)
|
||||
{
|
||||
double progressPercent = (double)testCount / totalTests * 100;
|
||||
LogManager.Info($"[ClashDetective进度] 已执行 {testCount}/{totalTests} 次检测 ({progressPercent:F1}%)");
|
||||
double logProgressPercent = (double)testCount / totalTests * 100;
|
||||
LogManager.Info($"[ClashDetective进度] 已执行 {testCount}/{totalTests} 次检测 ({logProgressPercent:F1}%)");
|
||||
}
|
||||
|
||||
var refreshedTempTest = _documentClash.TestsData.Tests.FirstOrDefault(t => t.DisplayName == tempTestName) as ClashTest;
|
||||
@ -966,6 +1004,12 @@ namespace NavisworksTransport
|
||||
}
|
||||
}
|
||||
|
||||
// 如果用户取消,直接返回,不执行后续操作(临时测试将在下方统一清理)
|
||||
if (wasCanceled)
|
||||
{
|
||||
LogManager.Info($"[分组测试] 检测已被用户取消,跳过结果处理和保存");
|
||||
}
|
||||
|
||||
// 🔥 优化4:批量删除所有临时测试
|
||||
if (tempTestsToRemove.Count > 0)
|
||||
{
|
||||
@ -983,6 +1027,15 @@ namespace NavisworksTransport
|
||||
}
|
||||
}
|
||||
|
||||
// 如果用户取消,直接返回,不执行后续操作
|
||||
if (wasCanceled)
|
||||
{
|
||||
return (null, addedMainTest, confirmedCount, true);
|
||||
}
|
||||
|
||||
// 完成进度条
|
||||
progress?.Update(1.0);
|
||||
|
||||
LogManager.Info($"[分组测试] ClashDetective检测完成: 执行 {testCount} 次检测, 确认碰撞 {confirmedCount} 组, 跳过 {skippedCount} 个冗余检测点");
|
||||
|
||||
// 第三步:处理碰撞结果
|
||||
@ -1067,7 +1120,7 @@ namespace NavisworksTransport
|
||||
LogManager.Info($"[ClashDetective] 结果已保存到数据库");
|
||||
|
||||
// 第四步:将分组添加到主测试(由调用方完成)
|
||||
return (collisionGroup, addedMainTest, confirmedCount);
|
||||
return (collisionGroup, addedMainTest, confirmedCount, false);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@ -1084,7 +1137,11 @@ namespace NavisworksTransport
|
||||
/// <param name="virtualVehicleWidth">虚拟车辆宽度(米)</param>
|
||||
/// <param name="virtualVehicleHeight">虚拟车辆高度(米)</param>
|
||||
/// <param name="pathPoints">路径点列表(用于测试完成后恢复物体位置)</param>
|
||||
public void CreateAllAnimationCollisionTests(
|
||||
/// <summary>
|
||||
/// 创建并运行ClashDetective碰撞测试
|
||||
/// </summary>
|
||||
/// <returns>true = 检测完成,false = 用户取消</returns>
|
||||
public bool CreateAllAnimationCollisionTests(
|
||||
List<CollisionResult> precomputedCollisions,
|
||||
double detectionGap,
|
||||
string routeId,
|
||||
@ -1097,6 +1154,9 @@ namespace NavisworksTransport
|
||||
double virtualVehicleHeight,
|
||||
List<Point3D> pathPoints = null)
|
||||
{
|
||||
// 重置取消标志
|
||||
_wasLastTestCanceled = false;
|
||||
|
||||
try
|
||||
{
|
||||
LogManager.Info($"=== 使用预计算碰撞数据创建ClashDetective测试(容差: {detectionGap}米)===");
|
||||
@ -1129,6 +1189,7 @@ namespace NavisworksTransport
|
||||
ClashTest addedMainTest = null;
|
||||
ClashResultGroup collisionGroup = null;
|
||||
int confirmedCount = 0;
|
||||
bool wasCanceled = false;
|
||||
|
||||
try
|
||||
{
|
||||
@ -1149,12 +1210,61 @@ namespace NavisworksTransport
|
||||
collisionGroup = result.collisionGroup;
|
||||
addedMainTest = result.addedMainTest;
|
||||
confirmedCount = result.confirmedCount;
|
||||
wasCanceled = result.wasCanceled;
|
||||
|
||||
// 检查是否被取消
|
||||
if (wasCanceled)
|
||||
{
|
||||
LogManager.Info("[CreateAllAnimationCollisionTests] 用户取消了碰撞检测");
|
||||
|
||||
// 设置取消标志
|
||||
_wasLastTestCanceled = true;
|
||||
|
||||
// 清空当前测试结果,避免取消后显示旧结果
|
||||
ClearCurrentTestCache();
|
||||
_currentTestName = null;
|
||||
_clashDetectiveCollisionCount = 0;
|
||||
|
||||
// 恢复物体状态
|
||||
if (animatedObject != null && IsModelItemValid(animatedObject))
|
||||
{
|
||||
PathAnimationManager.GetInstance().RestoreAnimatedObjectState(animatedObject);
|
||||
}
|
||||
|
||||
// 重置动画完成标志,允许重新运行动画
|
||||
ResetAnimationCompletedFlag(routeId);
|
||||
}
|
||||
}
|
||||
finally
|
||||
{
|
||||
// 先激活 Navisworks 主窗口(避免关闭进度条后丢失焦点)
|
||||
try
|
||||
{
|
||||
var mainWindow = Autodesk.Navisworks.Api.Application.Gui.MainWindow;
|
||||
if (mainWindow != null)
|
||||
{
|
||||
// 使用 Windows API 激活窗口
|
||||
SetForegroundWindow(mainWindow.Handle);
|
||||
LogManager.Debug("[ClashDetective] 已激活 Navisworks 主窗口");
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
LogManager.Debug($"[ClashDetective] 激活主窗口失败: {ex.Message}");
|
||||
}
|
||||
|
||||
// 关闭进度条
|
||||
Application.EndProgress();
|
||||
}
|
||||
|
||||
// 如果取消,显示提示消息后返回
|
||||
if (wasCanceled)
|
||||
{
|
||||
// 在 finally 之后显示消息对话框
|
||||
ShowCancellationMessage();
|
||||
return false; // 返回取消状态
|
||||
}
|
||||
|
||||
// UI操作:将分组添加到主测试
|
||||
if (collisionGroup != null && addedMainTest != null && collisionGroup.Children.Count > 0)
|
||||
{
|
||||
@ -1199,6 +1309,8 @@ namespace NavisworksTransport
|
||||
{
|
||||
LogManager.Error($"动画结束后创建测试失败: {ex.Message}");
|
||||
}
|
||||
|
||||
return !_wasLastTestCanceled; // 返回是否成功完成(未被取消)
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@ -1248,6 +1360,67 @@ namespace NavisworksTransport
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 显示碰撞检测取消提示消息
|
||||
/// </summary>
|
||||
private void ShowCancellationMessage()
|
||||
{
|
||||
try
|
||||
{
|
||||
// 获取 Navisworks 主窗口句柄作为父窗口
|
||||
var mainWindow = System.Windows.Forms.Form.FromHandle(
|
||||
Autodesk.Navisworks.Api.Application.Gui.MainWindow.Handle);
|
||||
|
||||
// 使用 Windows Forms 显示提示框,指定父窗口保持焦点
|
||||
System.Windows.Forms.MessageBox.Show(
|
||||
mainWindow,
|
||||
"碰撞检测已取消。\n\n您可以重新运行动画来重新检测碰撞。",
|
||||
"检测取消",
|
||||
System.Windows.Forms.MessageBoxButtons.OK,
|
||||
System.Windows.Forms.MessageBoxIcon.Information);
|
||||
|
||||
LogManager.Info("[ClashDetective] 已显示取消提示消息");
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
// 如果获取父窗口失败,使用默认方式
|
||||
System.Windows.Forms.MessageBox.Show(
|
||||
"碰撞检测已取消。\n\n您可以重新运行动画来重新检测碰撞。",
|
||||
"检测取消",
|
||||
System.Windows.Forms.MessageBoxButtons.OK,
|
||||
System.Windows.Forms.MessageBoxIcon.Information);
|
||||
|
||||
LogManager.Info("[ClashDetective] 已显示取消提示消息(无父窗口)");
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 重置动画完成标志,允许重新运行动画进行碰撞检测
|
||||
/// </summary>
|
||||
/// <param name="routeId">路径ID</param>
|
||||
private void ResetAnimationCompletedFlag(string routeId)
|
||||
{
|
||||
try
|
||||
{
|
||||
// 从已完成检测集合中移除该路径的哈希,允许重新检测
|
||||
var animManager = PathAnimationManager.GetInstance();
|
||||
if (animManager != null)
|
||||
{
|
||||
// 先尝试清除当前动画配置的检测记录
|
||||
animManager.ForceRecreateCollisionTest();
|
||||
|
||||
// 同时清除所有记录(确保万无一失)
|
||||
PathAnimationManager.ClearAllCollisionTestRecords();
|
||||
|
||||
LogManager.Info($"[ClashDetective] 已重置动画完成标志,允许重新检测。路径ID: {routeId}");
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
LogManager.Error($"重置动画完成标志失败: {ex.Message}");
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 检查ModelItem是否仍然有效
|
||||
/// </summary>
|
||||
@ -1352,6 +1525,18 @@ namespace NavisworksTransport
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 清空取消标志
|
||||
/// </summary>
|
||||
public void ClearWasLastTestCanceled()
|
||||
{
|
||||
if (_wasLastTestCanceled)
|
||||
{
|
||||
LogManager.Info("[ClashDetective] 清空取消标志");
|
||||
_wasLastTestCanceled = false;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 清空当前测试名称
|
||||
/// </summary>
|
||||
|
||||
@ -1802,6 +1802,16 @@ namespace NavisworksTransport.UI.WPF.ViewModels
|
||||
CanStopAnimation = false;
|
||||
UpdateMainStatus("动画已完成");
|
||||
UpdateMediaControlProperties(); // 更新媒体控制属性
|
||||
|
||||
// 检查检测是否被取消
|
||||
if (_clashIntegration?.WasLastTestCanceled == true)
|
||||
{
|
||||
LogManager.Info("[动画完成] 检测已被取消,跳过报告生成和高亮");
|
||||
// 重置取消标志
|
||||
_clashIntegration.ClearWasLastTestCanceled();
|
||||
break;
|
||||
}
|
||||
|
||||
// 先清除所有碰撞高亮(包括预计算和ClashDetective)
|
||||
ModelHighlightHelper.ClearCollisionHighlights();
|
||||
// 生成碰撞报告(无论有无碰撞)并等待完成
|
||||
|
||||
Loading…
Reference in New Issue
Block a user