数据库保存碰撞节点信息表和相关操作
This commit is contained in:
parent
97bf6dbecd
commit
40fce35bc8
@ -89,6 +89,7 @@ namespace NavisworksTransport.Core.Animation
|
||||
private static readonly Dictionary<string, List<AnimationFrame>> _animationFrameCache = new Dictionary<string, List<AnimationFrame>>(); // 动画帧缓存
|
||||
private static readonly Dictionary<string, List<CollisionResult>> _collisionResultCache = new Dictionary<string, List<CollisionResult>>(); // 碰撞结果缓存
|
||||
private ModelItem _animatedObject;
|
||||
private bool _isVirtualVehicle = false; // 是否使用虚拟车辆
|
||||
private List<Point3D> _pathPoints;
|
||||
private List<ModelItem> _manualCollisionTargets = new List<ModelItem>();
|
||||
private bool _manualCollisionOverrideEnabled = false;
|
||||
@ -1170,7 +1171,8 @@ namespace NavisworksTransport.Core.Animation
|
||||
_detectionGap,
|
||||
_pathName,
|
||||
_currentRouteId,
|
||||
_animatedObjectName,
|
||||
_animatedObject,
|
||||
_isVirtualVehicle,
|
||||
_animationFrameRate,
|
||||
_animationDuration
|
||||
);
|
||||
@ -2226,16 +2228,12 @@ namespace NavisworksTransport.Core.Animation
|
||||
/// <param name="durationSeconds">动画持续时间(秒)</param>
|
||||
/// <param name="pathName">路径名称</param>
|
||||
/// <param name="routeId">路由ID</param>
|
||||
public void CreateAnimation(ModelItem animatedObject, List<Point3D> pathPoints, double durationSeconds = 10.0, string pathName = "未知路径", string routeId = null)
|
||||
public void CreateAnimation(ModelItem animatedObject, List<Point3D> pathPoints, double durationSeconds = 10.0, string pathName = "未知路径", string routeId = null, bool isVirtualVehicle = false)
|
||||
{
|
||||
_pathName = pathName;
|
||||
_currentRouteId = routeId;
|
||||
_animatedObjectName = animatedObject?.DisplayName ?? "未知对象";
|
||||
_isVirtualVehicle = isVirtualVehicle; // 设置是否使用虚拟车辆
|
||||
|
||||
LogManager.Info($"[PathAnimationManager.CreateAnimation] 接收到参数: pathName='{pathName}', routeId='{routeId}', animatedObjectName='{_animatedObjectName}'");
|
||||
LogManager.Info($"[PathAnimationManager.CreateAnimation] 存储的值: _pathName='{_pathName}', _currentRouteId='{_currentRouteId}'");
|
||||
|
||||
// 注意:pathPoints参数已废弃,现在使用PathRoute
|
||||
SetupAnimation(animatedObject, durationSeconds, _route);
|
||||
SetState(AnimationState.Ready);
|
||||
}
|
||||
|
||||
@ -164,13 +164,38 @@ namespace NavisworksTransport
|
||||
/// 保存ClashDetective结果到数据库
|
||||
/// </summary>
|
||||
private void SaveClashDetectiveResultToDatabase(string pathName, string routeId, List<CollisionResult> clashResults,
|
||||
int frameRate, double duration, double detectionGap, string animatedObjectName)
|
||||
int frameRate, double duration, double detectionGap,
|
||||
ModelItem animatedObject, bool isVirtualVehicle)
|
||||
{
|
||||
try
|
||||
{
|
||||
var pathDatabase = PathPlanningManager.Instance?.GetPathDatabase();
|
||||
if (pathDatabase != null)
|
||||
{
|
||||
// 获取动画对象名称
|
||||
string animatedObjectName = "未知对象";
|
||||
if (!isVirtualVehicle && animatedObject != null)
|
||||
{
|
||||
animatedObjectName = ModelItemAnalysisHelper.GetSafeDisplayName(animatedObject);
|
||||
}
|
||||
else if (isVirtualVehicle)
|
||||
{
|
||||
animatedObjectName = "虚拟车辆";
|
||||
}
|
||||
|
||||
// 设置车辆路径信息
|
||||
string vehicleModelItemPath = null;
|
||||
|
||||
if (!isVirtualVehicle && animatedObject != null)
|
||||
{
|
||||
// 只有真实车辆才记录路径
|
||||
var paths = ModelItemAnalysisHelper.GetModelItemIndexPaths(animatedObject);
|
||||
if (paths.Count > 0)
|
||||
{
|
||||
vehicleModelItemPath = string.Join(";", paths);
|
||||
}
|
||||
}
|
||||
|
||||
var record = new ClashDetectiveResultRecord
|
||||
{
|
||||
TestName = _currentTestName,
|
||||
@ -183,10 +208,40 @@ namespace NavisworksTransport
|
||||
Duration = duration,
|
||||
DetectionGap = detectionGap,
|
||||
AnimatedObjectName = animatedObjectName,
|
||||
IsVirtualVehicle = isVirtualVehicle,
|
||||
VehicleModelItemPath = vehicleModelItemPath,
|
||||
CreatedAt = DateTime.Now
|
||||
};
|
||||
pathDatabase.SaveClashDetectiveResult(record);
|
||||
LogManager.Info($"ClashDetective结果已保存到数据库");
|
||||
var resultId = pathDatabase.SaveClashDetectiveResult(record);
|
||||
LogManager.Info($"ClashDetective结果已保存到数据库,Id={resultId}, IsVirtualVehicle={isVirtualVehicle}");
|
||||
|
||||
// 保存被撞物体信息(只保存Item2,不保存车辆Item1)
|
||||
var collisionObjects = new List<ClashDetectiveCollisionObjectRecord>();
|
||||
|
||||
foreach (var collision in clashResults)
|
||||
{
|
||||
// 只保存被撞到的物体(Item2)
|
||||
if (collision.Item2 != null)
|
||||
{
|
||||
var paths = ModelItemAnalysisHelper.GetModelItemIndexPaths(collision.Item2);
|
||||
foreach (var path in paths)
|
||||
{
|
||||
collisionObjects.Add(new ClashDetectiveCollisionObjectRecord
|
||||
{
|
||||
ResultId = resultId,
|
||||
ModelItemPath = path,
|
||||
DisplayName = ModelItemAnalysisHelper.GetSafeDisplayName(collision.Item2),
|
||||
ObjectName = ModelItemAnalysisHelper.GetSafeDisplayName(collision.Item2)
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (collisionObjects.Count > 0)
|
||||
{
|
||||
pathDatabase.SaveClashDetectiveCollisionObjects(resultId, collisionObjects);
|
||||
LogManager.Info($"已保存 {collisionObjects.Count} 个被撞物体到数据库");
|
||||
}
|
||||
|
||||
// 触发结果保存事件,通知UI刷新列表
|
||||
ClashDetectiveResultSaved?.Invoke(this, new ClashDetectiveResultSavedEventArgs(pathName, _currentTestName, clashResults.Count));
|
||||
@ -352,11 +407,13 @@ namespace NavisworksTransport
|
||||
/// <param name="detectionGap">检测间隙容差</param>
|
||||
/// <param name="pathName">路径名称</param>
|
||||
/// <param name="routeId">路由ID</param>
|
||||
/// <param name="animatedObjectName">动画对象名称</param>
|
||||
/// <param name="animatedObject">动画对象(如果是真实车辆)</param>
|
||||
/// <param name="isVirtualVehicle">是否使用虚拟车辆</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,
|
||||
string pathName = "未知路径", string routeId = null,
|
||||
ModelItem animatedObject = null, bool isVirtualVehicle = false,
|
||||
int frameRate = 30, double duration = 10.0)
|
||||
{
|
||||
try
|
||||
@ -387,7 +444,6 @@ namespace NavisworksTransport
|
||||
LogManager.Info($"[预计算处理] 原始记录: {precomputedCollisions.Count},有效碰撞: {_animationCollisionCount}");
|
||||
|
||||
// 获取动画对象和当前动画终点位置(用于后续恢复)
|
||||
ModelItem animatedObject = null;
|
||||
Point3D animationEndPosition = new Point3D(0, 0, 0);
|
||||
|
||||
if (collisionResults.Count > 0)
|
||||
@ -647,7 +703,7 @@ namespace NavisworksTransport
|
||||
_clashDetectiveCollisionCount = clashResults.Count;
|
||||
|
||||
// 保存到数据库
|
||||
SaveClashDetectiveResultToDatabase(pathName, routeId, clashResults, frameRate, duration, detectionGap, animatedObjectName);
|
||||
SaveClashDetectiveResultToDatabase(pathName, routeId, clashResults, frameRate, duration, detectionGap, animatedObject, isVirtualVehicle);
|
||||
|
||||
// 第四步:将分组添加到主测试
|
||||
if (collisionGroup.Children.Count > 0)
|
||||
|
||||
@ -170,16 +170,32 @@ namespace NavisworksTransport
|
||||
Duration REAL,
|
||||
DetectionGap REAL,
|
||||
AnimatedObjectName TEXT,
|
||||
IsVirtualVehicle INTEGER,
|
||||
VehicleModelItemPath TEXT,
|
||||
CreatedAt DATETIME DEFAULT CURRENT_TIMESTAMP
|
||||
)
|
||||
");
|
||||
|
||||
// 7. ClashDetective碰撞对象表
|
||||
ExecuteNonQuery(@"
|
||||
CREATE TABLE IF NOT EXISTS ClashDetectiveCollisionObjects (
|
||||
Id INTEGER PRIMARY KEY AUTOINCREMENT,
|
||||
ResultId INTEGER NOT NULL,
|
||||
ModelItemPath TEXT NOT NULL,
|
||||
DisplayName TEXT,
|
||||
ObjectName TEXT,
|
||||
FOREIGN KEY(ResultId) REFERENCES ClashDetectiveResults(Id) ON DELETE CASCADE
|
||||
)
|
||||
");
|
||||
|
||||
// 创建索引
|
||||
ExecuteNonQuery("CREATE INDEX IF NOT EXISTS idx_reports_route ON CollisionReports(RouteId)");
|
||||
ExecuteNonQuery("CREATE INDEX IF NOT EXISTS idx_pathpoints_route ON PathPoints(RouteId)");
|
||||
ExecuteNonQuery("CREATE INDEX IF NOT EXISTS idx_pathedges_route ON PathEdges(RouteId)");
|
||||
ExecuteNonQuery("CREATE INDEX IF NOT EXISTS idx_clash_path_name ON ClashDetectiveResults(PathName)");
|
||||
ExecuteNonQuery("CREATE INDEX IF NOT EXISTS idx_clash_test_time ON ClashDetectiveResults(TestTime DESC)");
|
||||
ExecuteNonQuery("CREATE INDEX IF NOT EXISTS idx_clash_objects_result ON ClashDetectiveCollisionObjects(ResultId)");
|
||||
ExecuteNonQuery("CREATE INDEX IF NOT EXISTS idx_clash_objects_path ON ClashDetectiveCollisionObjects(ModelItemPath)");
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@ -371,7 +387,7 @@ namespace NavisworksTransport
|
||||
/// <summary>
|
||||
/// 保存ClashDetective碰撞检测结果
|
||||
/// </summary>
|
||||
public void SaveClashDetectiveResult(ClashDetectiveResultRecord record)
|
||||
public int SaveClashDetectiveResult(ClashDetectiveResultRecord record)
|
||||
{
|
||||
try
|
||||
{
|
||||
@ -390,11 +406,12 @@ namespace NavisworksTransport
|
||||
var sql = @"
|
||||
INSERT INTO ClashDetectiveResults
|
||||
(TestName, PathName, RouteId, TestTime, CollisionCount, AnimationCollisionCount,
|
||||
FrameRate, Duration, DetectionGap, AnimatedObjectName, CreatedAt)
|
||||
FrameRate, Duration, DetectionGap, AnimatedObjectName, IsVirtualVehicle, VehicleModelItemPath, CreatedAt)
|
||||
VALUES (@testName, @pathName, @routeId, @testTime, @collisionCount, @animationCollisionCount,
|
||||
@frameRate, @duration, @detectionGap, @animatedObjectName, @createdAt)
|
||||
@frameRate, @duration, @detectionGap, @animatedObjectName, @isVirtualVehicle, @vehiclePath, @createdAt)
|
||||
";
|
||||
|
||||
long newId = 0;
|
||||
using (var cmd = new SQLiteCommand(sql, _connection))
|
||||
{
|
||||
cmd.Parameters.AddWithValue("@testName", record.TestName);
|
||||
@ -407,11 +424,15 @@ namespace NavisworksTransport
|
||||
cmd.Parameters.AddWithValue("@duration", record.Duration);
|
||||
cmd.Parameters.AddWithValue("@detectionGap", record.DetectionGap);
|
||||
cmd.Parameters.AddWithValue("@animatedObjectName", record.AnimatedObjectName ?? "");
|
||||
cmd.Parameters.AddWithValue("@isVirtualVehicle", record.IsVirtualVehicle);
|
||||
cmd.Parameters.AddWithValue("@vehiclePath", record.VehicleModelItemPath ?? "");
|
||||
cmd.Parameters.AddWithValue("@createdAt", record.CreatedAt);
|
||||
cmd.ExecuteNonQuery();
|
||||
newId = _connection.LastInsertRowId;
|
||||
}
|
||||
|
||||
LogManager.Info($"ClashDetective结果已保存: 测试={record.TestName}, 碰撞数={record.CollisionCount}");
|
||||
LogManager.Info($"ClashDetective结果已保存: 测试={record.TestName}, 碰撞数={record.CollisionCount}, Id={newId}");
|
||||
return (int)newId;
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
@ -541,6 +562,114 @@ namespace NavisworksTransport
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 保存ClashDetective碰撞对象
|
||||
/// </summary>
|
||||
public void SaveClashDetectiveCollisionObjects(int resultId, List<ClashDetectiveCollisionObjectRecord> objects)
|
||||
{
|
||||
if (objects == null || objects.Count == 0)
|
||||
return;
|
||||
|
||||
try
|
||||
{
|
||||
using (var transaction = _connection.BeginTransaction())
|
||||
{
|
||||
var sql = @"
|
||||
INSERT INTO ClashDetectiveCollisionObjects
|
||||
(ResultId, ModelItemPath, DisplayName, ObjectName)
|
||||
VALUES (@resultId, @path, @displayName, @objectName)
|
||||
";
|
||||
|
||||
foreach (var obj in objects)
|
||||
{
|
||||
using (var cmd = new SQLiteCommand(sql, _connection))
|
||||
{
|
||||
cmd.Parameters.AddWithValue("@resultId", resultId);
|
||||
cmd.Parameters.AddWithValue("@path", obj.ModelItemPath ?? "");
|
||||
cmd.Parameters.AddWithValue("@displayName", obj.DisplayName ?? "");
|
||||
cmd.Parameters.AddWithValue("@objectName", obj.ObjectName ?? "");
|
||||
cmd.ExecuteNonQuery();
|
||||
}
|
||||
}
|
||||
|
||||
transaction.Commit();
|
||||
LogManager.Info($"已保存 {objects.Count} 个碰撞对象到数据库,ResultId={resultId}");
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
LogManager.Error($"保存ClashDetective碰撞对象失败: {ex.Message}", ex);
|
||||
throw;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 获取指定ClashDetective结果的所有碰撞对象
|
||||
/// </summary>
|
||||
public List<ClashDetectiveCollisionObjectRecord> GetClashDetectiveCollisionObjects(int resultId)
|
||||
{
|
||||
var results = new List<ClashDetectiveCollisionObjectRecord>();
|
||||
|
||||
try
|
||||
{
|
||||
var sql = @"
|
||||
SELECT Id, ResultId, ModelItemPath, DisplayName, ObjectName
|
||||
FROM ClashDetectiveCollisionObjects
|
||||
WHERE ResultId = @resultId
|
||||
";
|
||||
|
||||
using (var cmd = new SQLiteCommand(sql, _connection))
|
||||
{
|
||||
cmd.Parameters.AddWithValue("@resultId", resultId);
|
||||
using (var reader = cmd.ExecuteReader())
|
||||
{
|
||||
while (reader.Read())
|
||||
{
|
||||
results.Add(new ClashDetectiveCollisionObjectRecord
|
||||
{
|
||||
Id = Convert.ToInt32(reader["Id"]),
|
||||
ResultId = Convert.ToInt32(reader["ResultId"]),
|
||||
ModelItemPath = reader["ModelItemPath"]?.ToString(),
|
||||
DisplayName = reader["DisplayName"]?.ToString(),
|
||||
ObjectName = reader["ObjectName"]?.ToString()
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
LogManager.Debug($"获取到 {results.Count} 个碰撞对象记录");
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
LogManager.Error($"获取ClashDetective碰撞对象失败: {ex.Message}", ex);
|
||||
}
|
||||
|
||||
return results;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 根据ModelItemPath查询碰撞次数
|
||||
/// </summary>
|
||||
public int GetCollisionCountByModelItemPath(string modelItemPath)
|
||||
{
|
||||
try
|
||||
{
|
||||
var sql = "SELECT COUNT(*) FROM ClashDetectiveCollisionObjects WHERE ModelItemPath = @path";
|
||||
|
||||
using (var cmd = new SQLiteCommand(sql, _connection))
|
||||
{
|
||||
cmd.Parameters.AddWithValue("@path", modelItemPath);
|
||||
var result = cmd.ExecuteScalar();
|
||||
return Convert.ToInt32(result);
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
LogManager.Error($"查询碰撞次数失败: {ex.Message}", ex);
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
/// <summary>
|
||||
@ -1067,9 +1196,23 @@ namespace NavisworksTransport
|
||||
public double Duration { get; set; }
|
||||
public double DetectionGap { get; set; }
|
||||
public string AnimatedObjectName { get; set; }
|
||||
public bool IsVirtualVehicle { get; set; }
|
||||
public string VehicleModelItemPath { get; set; }
|
||||
public DateTime CreatedAt { get; set; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// ClashDetective碰撞对象数据模型
|
||||
/// </summary>
|
||||
public class ClashDetectiveCollisionObjectRecord
|
||||
{
|
||||
public int Id { get; set; }
|
||||
public int ResultId { get; set; }
|
||||
public string ModelItemPath { get; set; }
|
||||
public string DisplayName { get; set; }
|
||||
public string ObjectName { get; set; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 路径分析结果数据模型
|
||||
/// </summary>
|
||||
|
||||
@ -2187,7 +2187,7 @@ namespace NavisworksTransport.UI.WPF.ViewModels
|
||||
// 先设置路径到动画管理器
|
||||
_pathAnimationManager.SetRoute(pathRoute);
|
||||
|
||||
_pathAnimationManager.CreateAnimation(animatedObject, pathPoints, AnimationDuration, CurrentPathRoute.Name, CurrentPathRoute.Id);
|
||||
_pathAnimationManager.CreateAnimation(animatedObject, pathPoints, AnimationDuration, CurrentPathRoute.Name, CurrentPathRoute.Id, UseVirtualVehicle);
|
||||
|
||||
var totalElapsed = (DateTime.Now - cacheStartTime).TotalMilliseconds;
|
||||
LogManager.Info($"[动画生成] 动画生成完成,总耗时: {totalElapsed:F1}ms");
|
||||
|
||||
Loading…
Reference in New Issue
Block a user