Fix batch queue detection record snapshots

This commit is contained in:
tian 2026-03-20 15:42:16 +08:00
parent c9a926356c
commit a651b69459
2 changed files with 140 additions and 137 deletions

View File

@ -391,6 +391,11 @@ namespace NavisworksTransport.Core
try
{
if (!item.DetectionRecordId.HasValue)
{
throw new InvalidOperationException("批处理队列项缺少 DetectionRecordId无法保存完整碰撞结果和位姿数据。请重新生成动画后再加入批处理。");
}
var pathRoute = await _database.GetPathRouteAsync(item.RouteId);
if (pathRoute == null)
{
@ -1072,4 +1077,4 @@ namespace NavisworksTransport.Core
{
public BatchQueueItem Item { get; set; }
}
}
}

View File

@ -3134,126 +3134,7 @@ namespace NavisworksTransport.UI.WPF.ViewModels
LogManager.Info($"[检测记录] 用户选择重新生成,创建新记录");
}
// 生成测试名称将在ClashDetective完成后更新为正式名称
string testName = $"动画检测_{DateTime.Now:MMdd_HHmmssfff}";
// 创建检测记录
var record = new CollisionDetectionRecord
{
RouteId = routeId,
CreatedTime = DateTime.Now,
FrameRate = _animationFrameRate,
DurationSeconds = AnimationDuration,
// 检测容差UI为米单位内部使用模型单位
DetectionTolerance = _detectionTolerance * UnitsConverter.GetMetersToUnitsConversionFactor(),
IsVirtualObject = UseVirtualObject,
AnimatedObjectName = UseVirtualObject ? "虚拟物体" : SelectedAnimatedObject?.DisplayName,
DetectAllObjects = !IsManualCollisionTargetEnabled,
ObjectRotationCorrection = _objectRotationCorrection,
Description = $"动画生成于 {DateTime.Now:yyyy-MM-dd HH:mm:ss}",
// 设置碰撞检测相关字段
TestName = testName,
TestTime = DateTime.Now,
CollisionCount = 0, // 初始为0将在ClashDetective完成后更新
AnimationCollisionCount = 0
};
// 虚拟物体尺寸(米 → 模型单位,数据库存储模型单位)
if (UseVirtualObject)
{
double metersToUnits = UnitsConverter.GetMetersToUnitsConversionFactor();
record.VirtualObjectLength = VirtualObjectLengthInMeters * metersToUnits;
record.VirtualObjectWidth = VirtualObjectWidthInMeters * metersToUnits;
record.VirtualObjectHeight = VirtualObjectHeightInMeters * metersToUnits;
}
// 真实物体信息
else if (SelectedAnimatedObject != null)
{
try
{
var pathId = Autodesk.Navisworks.Api.Application.ActiveDocument.Models.CreatePathId(SelectedAnimatedObject);
record.ObjectModelIndex = pathId.ModelIndex;
record.ObjectPathId = pathId.PathId;
}
catch (Exception ex)
{
LogManager.Warning($"[检测记录] 获取运动物体PathId失败: {ex.Message}");
}
}
// 保存检测记录
int recordId = pathDatabase.SaveCollisionDetectionRecord(record);
LogManager.Info($"[检测记录] 已创建记录 (Id={recordId})");
// 🔥 设置当前检测记录ID到PathAnimationManager供碰撞结果保存时关联使用
_pathAnimationManager.CurrentDetectionRecordId = recordId;
_pathAnimationManager.IsUsingHistoryRecord = false; // 新记录,不是历史记录
// 保存排除列表
var excludedObjects = _pathAnimationManager?.GetExcludedObjects();
if (excludedObjects != null && excludedObjects.Count > 0)
{
var excludedRecords = new List<CollisionDetectionExcludedObjectRecord>();
foreach (var obj in excludedObjects)
{
if (obj == null) continue;
try
{
var pathId = Autodesk.Navisworks.Api.Application.ActiveDocument.Models.CreatePathId(obj);
excludedRecords.Add(new CollisionDetectionExcludedObjectRecord
{
DetectionRecordId = recordId,
ModelIndex = pathId.ModelIndex,
PathId = pathId.PathId,
DisplayName = obj.DisplayName,
ObjectName = obj.DisplayName,
Reason = "预计算碰撞分析排除"
});
}
catch (Exception ex)
{
LogManager.Warning($"[检测记录] 准备排除对象记录失败: {obj.DisplayName}, {ex.Message}");
}
}
if (excludedRecords.Count > 0)
{
pathDatabase.SaveCollisionDetectionExcludedObjects(recordId, excludedRecords);
LogManager.Info($"[检测记录] 已保存 {excludedRecords.Count} 个排除对象");
}
}
// 保存手工目标
if (IsManualCollisionTargetEnabled && _manualCollisionTargets != null && _manualCollisionTargets.Count > 0)
{
var manualTargetRecords = new List<CollisionDetectionManualTargetRecord>();
foreach (var target in _manualCollisionTargets)
{
if (target?.ModelItem == null) continue;
try
{
var pathId = Autodesk.Navisworks.Api.Application.ActiveDocument.Models.CreatePathId(target.ModelItem);
manualTargetRecords.Add(new CollisionDetectionManualTargetRecord
{
DetectionRecordId = recordId,
ModelIndex = pathId.ModelIndex,
PathId = pathId.PathId,
DisplayName = target.ModelItem.DisplayName,
ObjectName = target.ModelItem.DisplayName
});
}
catch (Exception ex)
{
LogManager.Warning($"[检测记录] 准备手工目标记录失败: {target.DisplayName}, {ex.Message}");
}
}
if (manualTargetRecords.Count > 0)
{
pathDatabase.SaveCollisionDetectionManualTargets(recordId, manualTargetRecords);
LogManager.Info($"[检测记录] 已保存 {manualTargetRecords.Count} 个手工目标");
}
}
int recordId = CreateCollisionDetectionRecordSnapshot("动画生成", bindToAnimationManager: true);
// 🔥 注册动画配置哈希与检测记录ID的映射用于后续检查重复配置
try
@ -3280,6 +3161,136 @@ namespace NavisworksTransport.UI.WPF.ViewModels
}
}
/// <summary>
/// 创建碰撞检测记录快照。
/// 生成动画和批处理都应该创建自己的配置快照,不依赖旧检测结果。
/// </summary>
private int CreateCollisionDetectionRecordSnapshot(string scenarioName, bool bindToAnimationManager)
{
var pathDatabase = _pathPlanningManager?.GetPathDatabase();
if (pathDatabase == null)
{
throw new InvalidOperationException("数据库未初始化,无法保存检测记录");
}
string routeId = CurrentPathRoute?.Id ?? string.Empty;
string testName = $"{scenarioName}_{DateTime.Now:MMdd_HHmmssfff}";
double metersToUnits = UnitsConverter.GetMetersToUnitsConversionFactor();
var record = new CollisionDetectionRecord
{
RouteId = routeId,
CreatedTime = DateTime.Now,
FrameRate = _animationFrameRate,
DurationSeconds = AnimationDuration,
DetectionTolerance = _detectionTolerance * metersToUnits,
IsVirtualObject = UseVirtualObject,
AnimatedObjectName = UseVirtualObject ? "虚拟物体" : SelectedAnimatedObject?.DisplayName,
DetectAllObjects = !IsManualCollisionTargetEnabled,
ObjectRotationCorrection = _objectRotationCorrection,
Description = $"{scenarioName}于 {DateTime.Now:yyyy-MM-dd HH:mm:ss}",
TestName = testName,
TestTime = DateTime.Now,
CollisionCount = 0,
AnimationCollisionCount = 0
};
if (UseVirtualObject)
{
record.VirtualObjectLength = VirtualObjectLengthInMeters * metersToUnits;
record.VirtualObjectWidth = VirtualObjectWidthInMeters * metersToUnits;
record.VirtualObjectHeight = VirtualObjectHeightInMeters * metersToUnits;
}
else if (SelectedAnimatedObject != null)
{
try
{
var pathId = Autodesk.Navisworks.Api.Application.ActiveDocument.Models.CreatePathId(SelectedAnimatedObject);
record.ObjectModelIndex = pathId.ModelIndex;
record.ObjectPathId = pathId.PathId;
}
catch (Exception ex)
{
LogManager.Warning($"[检测记录] 获取运动物体PathId失败: {ex.Message}");
}
}
int recordId = pathDatabase.SaveCollisionDetectionRecord(record);
LogManager.Info($"[检测记录] 已创建{scenarioName}记录 (Id={recordId})");
if (bindToAnimationManager)
{
_pathAnimationManager.CurrentDetectionRecordId = recordId;
_pathAnimationManager.IsUsingHistoryRecord = false;
}
var excludedObjects = _pathAnimationManager?.GetExcludedObjects();
if (excludedObjects != null && excludedObjects.Count > 0)
{
var excludedRecords = new List<CollisionDetectionExcludedObjectRecord>();
foreach (var obj in excludedObjects)
{
if (obj == null) continue;
try
{
var pathId = Autodesk.Navisworks.Api.Application.ActiveDocument.Models.CreatePathId(obj);
excludedRecords.Add(new CollisionDetectionExcludedObjectRecord
{
DetectionRecordId = recordId,
ModelIndex = pathId.ModelIndex,
PathId = pathId.PathId,
DisplayName = obj.DisplayName,
ObjectName = obj.DisplayName,
Reason = "预计算碰撞分析排除"
});
}
catch (Exception ex)
{
LogManager.Warning($"[检测记录] 准备排除对象记录失败: {obj.DisplayName}, {ex.Message}");
}
}
if (excludedRecords.Count > 0)
{
pathDatabase.SaveCollisionDetectionExcludedObjects(recordId, excludedRecords);
LogManager.Info($"[检测记录] 已保存 {excludedRecords.Count} 个排除对象");
}
}
if (IsManualCollisionTargetEnabled && _manualCollisionTargets != null && _manualCollisionTargets.Count > 0)
{
var manualTargetRecords = new List<CollisionDetectionManualTargetRecord>();
foreach (var target in _manualCollisionTargets)
{
if (target?.ModelItem == null) continue;
try
{
var pathId = Autodesk.Navisworks.Api.Application.ActiveDocument.Models.CreatePathId(target.ModelItem);
manualTargetRecords.Add(new CollisionDetectionManualTargetRecord
{
DetectionRecordId = recordId,
ModelIndex = pathId.ModelIndex,
PathId = pathId.PathId,
DisplayName = target.ModelItem.DisplayName,
ObjectName = target.ModelItem.DisplayName
});
}
catch (Exception ex)
{
LogManager.Warning($"[检测记录] 准备手工目标记录失败: {target.DisplayName}, {ex.Message}");
}
}
if (manualTargetRecords.Count > 0)
{
pathDatabase.SaveCollisionDetectionManualTargets(recordId, manualTargetRecords);
LogManager.Info($"[检测记录] 已保存 {manualTargetRecords.Count} 个手工目标");
}
}
return recordId;
}
/// <summary>
/// 用户选择析析
/// </summary>
@ -5210,22 +5221,9 @@ namespace NavisworksTransport.UI.WPF.ViewModels
LogManager.Info($"[批处理] 添加路径到批处理队列: {CurrentPathRoute.Name}");
// 🔥 获取该路径最新的检测记录ID
int? detectionRecordId = null;
var pathDatabase = _pathPlanningManager?.GetPathDatabase();
if (pathDatabase != null)
{
var latestRecord = pathDatabase.GetLatestCollisionDetectionRecord(CurrentPathRoute.Id);
detectionRecordId = latestRecord?.Id;
if (detectionRecordId.HasValue)
{
LogManager.Info($"[批处理] 关联检测记录 (Id={detectionRecordId})");
}
else
{
LogManager.Warning("[批处理] 未找到检测记录,请先运行\"生成动画\"");
}
}
// 为批处理创建独立的检测记录快照,保存当前配置、排除列表和手工目标
int detectionRecordId = CreateCollisionDetectionRecordSnapshot("批处理任务创建", bindToAnimationManager: false);
LogManager.Info($"[批处理] 已创建批处理检测记录 (Id={detectionRecordId})");
// 创建批处理队列项
// 注意:虚拟物体尺寸需要从米转换为模型单位存入数据库