把碰撞报告保存到数据库,修改碰撞报告格式
This commit is contained in:
parent
e46931311f
commit
8cd988279f
@ -144,7 +144,7 @@
|
||||
<Compile Include="src\Commands\ImportPathCommand.cs" />
|
||||
<Compile Include="src\Commands\SetLogisticsAttributeCommand.cs" />
|
||||
<Compile Include="src\Commands\StartAnimationCommand.cs" />
|
||||
<Compile Include="src\Commands\ViewCollisionReportCommand.cs" />
|
||||
<Compile Include="src\Commands\GenerateCollisionReportCommand.cs" />
|
||||
|
||||
<!-- Core - Animation System -->
|
||||
<Compile Include="src\Core\Animation\PathAnimationManager.cs" />
|
||||
|
||||
@ -84,12 +84,18 @@ namespace NavisworksTransport.Commands
|
||||
// 新增:被撞物体清单
|
||||
public List<string> CollidedObjectsList { get; set; } = new List<string>();
|
||||
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;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 查看碰撞报告Command
|
||||
/// 生成碰撞报告Command
|
||||
/// </summary>
|
||||
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
|
||||
/// <summary>
|
||||
/// 创建综合报告命令
|
||||
/// </summary>
|
||||
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,
|
||||
@ -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
|
||||
/// </summary>
|
||||
public double DetectionGap => _detectionGap;
|
||||
|
||||
/// <summary>
|
||||
/// 获取路径名称
|
||||
/// </summary>
|
||||
public string PathName => _pathName;
|
||||
|
||||
/// <summary>
|
||||
/// 获取动画时长
|
||||
/// </summary>
|
||||
public double AnimationDuration => _animationDuration;
|
||||
|
||||
/// <summary>
|
||||
/// 设置并触发状态变更事件
|
||||
/// </summary>
|
||||
@ -1982,9 +2002,16 @@ namespace NavisworksTransport.Core.Animation
|
||||
/// <param name="pathPoints">路径点列表</param>
|
||||
/// <param name="durationSeconds">动画持续时间(秒)</param>
|
||||
/// <param name="pathName">路径名称</param>
|
||||
public void CreateAnimation(ModelItem animatedObject, List<Point3D> pathPoints, double durationSeconds = 10.0, string pathName = "未知路径")
|
||||
/// <param name="routeId">路由ID</param>
|
||||
public void CreateAnimation(ModelItem animatedObject, List<Point3D> 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);
|
||||
}
|
||||
|
||||
@ -244,7 +244,13 @@ namespace NavisworksTransport
|
||||
/// <param name="precomputedCollisions">预计算碰撞结果</param>
|
||||
/// <param name="detectionGap">检测间隙容差</param>
|
||||
/// <param name="pathName">路径名称</param>
|
||||
public void CreateAllAnimationCollisionTests(List<CollisionResult> precomputedCollisions, double detectionGap = 0.05, string pathName = "未知路径")
|
||||
/// <param name="routeId">路由ID</param>
|
||||
/// <param name="animatedObjectName">动画对象名称</param>
|
||||
/// <param name="frameRate">帧率</param>
|
||||
/// <param name="duration">动画时长</param>
|
||||
public void CreateAllAnimationCollisionTests(List<CollisionResult> 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)
|
||||
|
||||
@ -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
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 保存路径的碰撞结果
|
||||
/// 保存碰撞报告
|
||||
/// </summary>
|
||||
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;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 保存路径的碰撞结果(已废弃,保留以兼容旧代码)
|
||||
/// </summary>
|
||||
public void SaveCollisions(string routeId, List<CollisionResult> collisions)
|
||||
{
|
||||
|
||||
@ -2843,6 +2843,18 @@ namespace NavisworksTransport
|
||||
|
||||
#endregion
|
||||
|
||||
#region 公共访问方法
|
||||
|
||||
/// <summary>
|
||||
/// 获取PathDatabase实例
|
||||
/// </summary>
|
||||
public PathDatabase GetPathDatabase()
|
||||
{
|
||||
return _pathDatabase;
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region 自动路径规划辅助方法
|
||||
|
||||
/// <summary>
|
||||
|
||||
@ -156,6 +156,7 @@ namespace NavisworksTransport.UI.WPF.ViewModels
|
||||
{
|
||||
#region 私有字段
|
||||
|
||||
private string _id;
|
||||
private string _name;
|
||||
private ObservableCollection<PathPointViewModel> _points;
|
||||
private bool _isActive;
|
||||
@ -176,6 +177,15 @@ namespace NavisworksTransport.UI.WPF.ViewModels
|
||||
|
||||
#region 公共属性
|
||||
|
||||
/// <summary>
|
||||
/// 路径ID
|
||||
/// </summary>
|
||||
public string Id
|
||||
{
|
||||
get => _id;
|
||||
set => SetProperty(ref _id, value);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 路径名称
|
||||
/// </summary>
|
||||
@ -380,6 +390,7 @@ namespace NavisworksTransport.UI.WPF.ViewModels
|
||||
/// </summary>
|
||||
private void InitializeDefaults()
|
||||
{
|
||||
_id = Guid.NewGuid().ToString();
|
||||
_name = "新路径";
|
||||
_description = "";
|
||||
_isActive = false;
|
||||
|
||||
@ -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
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// 查看碰撞报告命令
|
||||
/// 查看碰撞报告命令(显示已缓存的报告)
|
||||
/// </summary>
|
||||
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
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// 处理碰撞检测事件
|
||||
/// 处理碰撞检测事件 - 自动生成报告并保存数据库
|
||||
/// </summary>
|
||||
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<CollisionReportResult> 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;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 保存碰撞报告到数据库
|
||||
/// </summary>
|
||||
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);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@ -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}");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -80,6 +80,10 @@ namespace NavisworksTransport.UI.WPF.ViewModels
|
||||
private string _movingObjectInfo;
|
||||
private ObservableCollection<string> _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);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 路径名称
|
||||
/// </summary>
|
||||
public string PathName
|
||||
{
|
||||
get => _pathName;
|
||||
set => SetProperty(ref _pathName, value);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 动画帧率
|
||||
/// </summary>
|
||||
public int FrameRate
|
||||
{
|
||||
get => _frameRate;
|
||||
set => SetProperty(ref _frameRate, value);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 动画时长
|
||||
/// </summary>
|
||||
public double Duration
|
||||
{
|
||||
get => _duration;
|
||||
set => SetProperty(ref _duration, value);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 检测间隙
|
||||
/// </summary>
|
||||
public double DetectionGap
|
||||
{
|
||||
get => _detectionGap;
|
||||
set => SetProperty(ref _detectionGap, value);
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region 命令属性
|
||||
@ -217,10 +257,6 @@ namespace NavisworksTransport.UI.WPF.ViewModels
|
||||
/// </summary>
|
||||
public ICommand CloseCommand { get; }
|
||||
|
||||
/// <summary>
|
||||
/// 刷新报告命令
|
||||
/// </summary>
|
||||
public ICommand RefreshReportCommand { get; }
|
||||
|
||||
/// <summary>
|
||||
/// 高亮碰撞对象命令
|
||||
@ -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<CollisionReportItem>(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($"<h1>NavisworksTransport 碰撞检测报告</h1>");
|
||||
html.AppendLine($"<p style='text-align: center; color: #666;'>生成时间: {now:yyyy年MM月dd日 HH:mm:ss}</p>");
|
||||
html.AppendLine($"<p style='text-align: center; color: #666;'>报告类型: {Statistics.ReportType}</p>");
|
||||
html.AppendLine($"<p style='text-align: center; color: #666;'>路径名称: {PathName}</p>");
|
||||
|
||||
// 总体统计
|
||||
html.AppendLine("<div class='summary'>");
|
||||
@ -724,14 +763,21 @@ namespace NavisworksTransport.UI.WPF.ViewModels
|
||||
html.AppendLine("</div>");
|
||||
html.AppendLine("</div>");
|
||||
|
||||
// 状态分布
|
||||
html.AppendLine("<h2>状态分布</h2>");
|
||||
html.AppendLine("<div class='status-grid'>");
|
||||
html.AppendLine($"<div class='status-item'><strong>新发现</strong><br>{Statistics.NewCollisions}</div>");
|
||||
html.AppendLine($"<div class='status-item'><strong>活跃</strong><br>{Statistics.ActiveCollisions}</div>");
|
||||
html.AppendLine($"<div class='status-item'><strong>已审阅</strong><br>{Statistics.ReviewedCollisions}</div>");
|
||||
html.AppendLine($"<div class='status-item'><strong>已批准</strong><br>{Statistics.ApprovedCollisions}</div>");
|
||||
html.AppendLine($"<div class='status-item'><strong>已解决</strong><br>{Statistics.ResolvedCollisions}</div>");
|
||||
// 动画参数
|
||||
html.AppendLine("<h2>动画参数</h2>");
|
||||
html.AppendLine("<div class='stats-grid'>");
|
||||
html.AppendLine("<div class='stat-item'>");
|
||||
html.AppendLine("<div class='stat-label'>帧率</div>");
|
||||
html.AppendLine($"<div class='stat-value'>{FrameRate} FPS</div>");
|
||||
html.AppendLine("</div>");
|
||||
html.AppendLine("<div class='stat-item'>");
|
||||
html.AppendLine("<div class='stat-label'>时长</div>");
|
||||
html.AppendLine($"<div class='stat-value'>{Duration:F1} 秒</div>");
|
||||
html.AppendLine("</div>");
|
||||
html.AppendLine("<div class='stat-item'>");
|
||||
html.AppendLine("<div class='stat-label'>检测间隙</div>");
|
||||
html.AppendLine($"<div class='stat-value'>{DetectionGap:F2} 米</div>");
|
||||
html.AppendLine("</div>");
|
||||
html.AppendLine("</div>");
|
||||
|
||||
// 运动构件信息
|
||||
@ -828,41 +874,6 @@ namespace NavisworksTransport.UI.WPF.ViewModels
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 刷新报告
|
||||
/// </summary>
|
||||
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<CollisionReportResult> reportResult)
|
||||
{
|
||||
InitializeReport(reportResult.Data);
|
||||
}
|
||||
else
|
||||
{
|
||||
SetFailedReport(result.Message);
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
LogManager.Error($"刷新碰撞报告失败: {ex.Message}");
|
||||
SetFailedReport(ex.Message);
|
||||
}
|
||||
finally
|
||||
{
|
||||
IsGenerating = false;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 高亮碰撞对象
|
||||
/// </summary>
|
||||
|
||||
@ -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 // 历史路径默认不激活
|
||||
|
||||
@ -224,37 +224,47 @@ NavisworksTransport 碰撞检测报告对话框 - 采用与主界面一致的Nav
|
||||
</Border>
|
||||
</UniformGrid>
|
||||
|
||||
<!-- 按状态分类统计 -->
|
||||
<Label Content="状态分布" Style="{StaticResource SectionHeaderStyle}"/>
|
||||
<UniformGrid Columns="5" Margin="0,0,0,15">
|
||||
<!-- 检测参数信息 -->
|
||||
<Label Content="检测参数" Style="{StaticResource SectionHeaderStyle}"/>
|
||||
<UniformGrid Columns="4" Margin="0,0,0,15">
|
||||
<Border Style="{StaticResource StatisticItemStyle}">
|
||||
<Grid>
|
||||
<TextBlock Text="新发现" Style="{StaticResource StatisticLabelStyle}" VerticalAlignment="Center"/>
|
||||
<TextBlock Text="{Binding Statistics.NewCollisions}" Style="{StaticResource StatisticValueStyle}"/>
|
||||
<Grid.RowDefinitions>
|
||||
<RowDefinition Height="Auto"/>
|
||||
<RowDefinition Height="Auto"/>
|
||||
</Grid.RowDefinitions>
|
||||
<TextBlock Grid.Row="0" Text="路径名称" Style="{StaticResource StatisticLabelStyle}"/>
|
||||
<TextBlock Grid.Row="1" Text="{Binding PathName}" Style="{StaticResource StatisticValueStyle}" FontSize="11"/>
|
||||
</Grid>
|
||||
</Border>
|
||||
<Border Style="{StaticResource StatisticItemStyle}">
|
||||
<Grid>
|
||||
<TextBlock Text="活跃" Style="{StaticResource StatisticLabelStyle}" VerticalAlignment="Center"/>
|
||||
<TextBlock Text="{Binding Statistics.ActiveCollisions}" Style="{StaticResource StatisticValueStyle}"/>
|
||||
<Grid.RowDefinitions>
|
||||
<RowDefinition Height="Auto"/>
|
||||
<RowDefinition Height="Auto"/>
|
||||
</Grid.RowDefinitions>
|
||||
<TextBlock Grid.Row="0" Text="帧率(FPS)" Style="{StaticResource StatisticLabelStyle}"/>
|
||||
<TextBlock Grid.Row="1" Text="{Binding FrameRate}" Style="{StaticResource StatisticValueStyle}"/>
|
||||
</Grid>
|
||||
</Border>
|
||||
<Border Style="{StaticResource StatisticItemStyle}">
|
||||
<Grid>
|
||||
<TextBlock Text="已审阅" Style="{StaticResource StatisticLabelStyle}" VerticalAlignment="Center"/>
|
||||
<TextBlock Text="{Binding Statistics.ReviewedCollisions}" Style="{StaticResource StatisticValueStyle}"/>
|
||||
<Grid.RowDefinitions>
|
||||
<RowDefinition Height="Auto"/>
|
||||
<RowDefinition Height="Auto"/>
|
||||
</Grid.RowDefinitions>
|
||||
<TextBlock Grid.Row="0" Text="时长(秒)" Style="{StaticResource StatisticLabelStyle}"/>
|
||||
<TextBlock Grid.Row="1" Text="{Binding Duration}" Style="{StaticResource StatisticValueStyle}"/>
|
||||
</Grid>
|
||||
</Border>
|
||||
<Border Style="{StaticResource StatisticItemStyle}">
|
||||
<Grid>
|
||||
<TextBlock Text="已批准" Style="{StaticResource StatisticLabelStyle}" VerticalAlignment="Center"/>
|
||||
<TextBlock Text="{Binding Statistics.ApprovedCollisions}" Style="{StaticResource StatisticValueStyle}"/>
|
||||
</Grid>
|
||||
</Border>
|
||||
<Border Style="{StaticResource StatisticItemStyle}">
|
||||
<Grid>
|
||||
<TextBlock Text="已解决" Style="{StaticResource StatisticLabelStyle}" VerticalAlignment="Center"/>
|
||||
<TextBlock Text="{Binding Statistics.ResolvedCollisions}" Style="{StaticResource StatisticValueStyle}"/>
|
||||
<Grid.RowDefinitions>
|
||||
<RowDefinition Height="Auto"/>
|
||||
<RowDefinition Height="Auto"/>
|
||||
</Grid.RowDefinitions>
|
||||
<TextBlock Grid.Row="0" Text="检测间隙(米)" Style="{StaticResource StatisticLabelStyle}"/>
|
||||
<TextBlock Grid.Row="1" Text="{Binding DetectionGap}" Style="{StaticResource StatisticValueStyle}"/>
|
||||
</Grid>
|
||||
</Border>
|
||||
</UniformGrid>
|
||||
@ -364,12 +374,6 @@ NavisworksTransport 碰撞检测报告对话框 - 采用与主界面一致的Nav
|
||||
<StackPanel Orientation="Horizontal"
|
||||
HorizontalAlignment="Right">
|
||||
|
||||
<Button Content="刷新报告"
|
||||
Command="{Binding RefreshReportCommand}"
|
||||
Style="{StaticResource SecondaryButtonStyle}"
|
||||
Margin="0,0,10,0"
|
||||
Visibility="{Binding IsGenerating, Converter={StaticResource InverseBooleanToVisibilityConverter}}"/>
|
||||
|
||||
<Button Content="导出报告"
|
||||
Command="{Binding ExportReportCommand}"
|
||||
Style="{StaticResource SecondaryButtonStyle}"
|
||||
|
||||
Loading…
Reference in New Issue
Block a user