优化运动物体和碰撞目标的存储逻辑,更新数据库结构
This commit is contained in:
parent
1e277a4bc3
commit
c1e20bf4ee
@ -252,25 +252,14 @@ namespace NavisworksTransport.Core
|
||||
{
|
||||
throw new InvalidOperationException($"路径不存在 (Id: {item.PathRouteId})");
|
||||
}
|
||||
|
||||
|
||||
// 获取运动物体
|
||||
ModelItem animatedObject = null;
|
||||
bool isVirtualVehicle = item.IsVirtualVehicle;
|
||||
if (!string.IsNullOrEmpty(item.VehicleObjectId))
|
||||
{
|
||||
animatedObject = FindModelItemById(item.VehicleObjectId);
|
||||
isVirtualVehicle = false;
|
||||
|
||||
if (animatedObject == null)
|
||||
{
|
||||
throw new InvalidOperationException("未找到指定的运动物体");
|
||||
}
|
||||
|
||||
LogManager.Info($"[批处理] 使用真实物体: {animatedObject.DisplayName}");
|
||||
}
|
||||
else if (isVirtualVehicle)
|
||||
if (isVirtualVehicle)
|
||||
{
|
||||
// 🔥 使用现有的虚拟车辆,不创建和清理
|
||||
// 使用现有的虚拟车辆,不创建和清理
|
||||
// ShowVirtualVehicle 会显示虚拟车辆并更新尺寸(如果已存在)
|
||||
VirtualVehicleManager.Instance.ShowVirtualVehicle(
|
||||
item.VirtualVehicleLength,
|
||||
@ -287,27 +276,108 @@ namespace NavisworksTransport.Core
|
||||
|
||||
LogManager.Info($"[批处理] 使用虚拟车辆: {animatedObject.DisplayName}");
|
||||
}
|
||||
|
||||
// 初始化碰撞检测缓存
|
||||
LogManager.Info("[批处理] 初始化碰撞检测缓存...");
|
||||
ClashDetectiveIntegration.InitializeCollisionDetectionCache(animatedObject);
|
||||
|
||||
// 在主线程执行Navisworks API调用
|
||||
var result = await UIStateManager.Instance.ExecuteUIUpdateAsync(() =>
|
||||
else
|
||||
{
|
||||
// 预计算动画帧和碰撞
|
||||
var config = new CollisionDetectionConfig
|
||||
{
|
||||
FrameRate = item.FrameRate,
|
||||
DurationSeconds = item.DurationSeconds,
|
||||
DetectionToleranceMeters = item.DetectionToleranceMeters,
|
||||
VirtualVehicleLength = item.VirtualVehicleLength,
|
||||
VirtualVehicleWidth = item.VirtualVehicleWidth,
|
||||
VirtualVehicleHeight = item.VirtualVehicleHeight,
|
||||
CollisionDetectionEnabled = true,
|
||||
ReportGenerationEnabled = true
|
||||
};
|
||||
// 从 ModelItemReferences 表查询运动物体
|
||||
var vehicleReferences = await _database.GetModelItemReferencesAsync(
|
||||
item.Id,
|
||||
"BatchQueueItem",
|
||||
"Vehicle"
|
||||
);
|
||||
|
||||
if (vehicleReferences.Count > 0)
|
||||
{
|
||||
var vehicleRef = vehicleReferences[0];
|
||||
try
|
||||
{
|
||||
var pathIdObj = new Autodesk.Navisworks.Api.DocumentParts.ModelItemPathId
|
||||
{
|
||||
ModelIndex = vehicleRef.Item1,
|
||||
PathId = vehicleRef.Item2
|
||||
};
|
||||
animatedObject = Application.ActiveDocument.Models.ResolvePathId(pathIdObj);
|
||||
|
||||
if (animatedObject == null)
|
||||
{
|
||||
throw new InvalidOperationException("未找到指定的运动物体");
|
||||
}
|
||||
|
||||
LogManager.Info($"[批处理] 使用真实物体: {animatedObject.DisplayName}");
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
LogManager.Error($"[批处理] 从 PathId 恢复运动物体失败: ModelIndex={vehicleRef.Item1}, PathId={vehicleRef.Item2}, 错误: {ex.Message}");
|
||||
throw new InvalidOperationException("恢复运动物体失败", ex);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
throw new InvalidOperationException("未找到运动物体的 ModelItem 引用");
|
||||
}
|
||||
}
|
||||
|
||||
// 初始化碰撞检测缓存
|
||||
LogManager.Info("[批处理] 初始化碰撞检测缓存...");
|
||||
ClashDetectiveIntegration.InitializeCollisionDetectionCache(animatedObject);
|
||||
|
||||
// 从 ModelItemReferences 表查询手工指定的检测物体(在主线程外完成查询)
|
||||
List<ModelItem> manualDetectionTargets = null;
|
||||
if (!item.DetectAllObjects)
|
||||
{
|
||||
var targetReferences = await _database.GetModelItemReferencesAsync(
|
||||
item.Id,
|
||||
"BatchQueueItem",
|
||||
"CollisionTarget"
|
||||
);
|
||||
|
||||
if (targetReferences.Count > 0)
|
||||
{
|
||||
manualDetectionTargets = new List<ModelItem>();
|
||||
var doc = Autodesk.Navisworks.Api.Application.ActiveDocument;
|
||||
|
||||
foreach (var targetRef in targetReferences)
|
||||
{
|
||||
try
|
||||
{
|
||||
var pathIdObj = new Autodesk.Navisworks.Api.DocumentParts.ModelItemPathId
|
||||
{
|
||||
ModelIndex = targetRef.Item1,
|
||||
PathId = targetRef.Item2
|
||||
};
|
||||
var modelItem = doc.Models.ResolvePathId(pathIdObj);
|
||||
if (modelItem != null)
|
||||
{
|
||||
manualDetectionTargets.Add(modelItem);
|
||||
}
|
||||
else
|
||||
{
|
||||
LogManager.Warning($"[批处理] 无法通过 PathId 找到 ModelItem: ModelIndex={targetRef.Item1}, PathId={targetRef.Item2}");
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
LogManager.Warning($"[批处理] 恢复手工指定对象失败: {targetRef.Item3}, 错误: {ex.Message}");
|
||||
}
|
||||
}
|
||||
LogManager.Info($"[批处理] 加载手工指定检测物体,成功: {manualDetectionTargets.Count}/{targetReferences.Count}");
|
||||
}
|
||||
}
|
||||
|
||||
// 在主线程执行Navisworks API调用
|
||||
var result = await UIStateManager.Instance.ExecuteUIUpdateAsync(() =>
|
||||
{
|
||||
// 预计算动画帧和碰撞
|
||||
var config = new CollisionDetectionConfig
|
||||
{
|
||||
FrameRate = item.FrameRate,
|
||||
DurationSeconds = item.DurationSeconds,
|
||||
DetectionToleranceMeters = item.DetectionToleranceMeters,
|
||||
VirtualVehicleLength = item.VirtualVehicleLength,
|
||||
VirtualVehicleWidth = item.VirtualVehicleWidth,
|
||||
VirtualVehicleHeight = item.VirtualVehicleHeight,
|
||||
CollisionDetectionEnabled = true,
|
||||
ReportGenerationEnabled = true
|
||||
};
|
||||
var frames = _processor.PrecomputeFrames(
|
||||
pathRoute,
|
||||
animatedObject,
|
||||
@ -318,7 +388,7 @@ namespace NavisworksTransport.Core
|
||||
config.FrameRate,
|
||||
config.DurationSeconds,
|
||||
config.DetectionToleranceMeters,
|
||||
null,
|
||||
manualDetectionTargets,
|
||||
item.ObjectRotationCorrection
|
||||
);
|
||||
|
||||
@ -455,28 +525,7 @@ namespace NavisworksTransport.Core
|
||||
await _database.DeleteBatchQueueItemAsync(itemId);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 查找模型项
|
||||
/// </summary>
|
||||
private ModelItem FindModelItemById(string id)
|
||||
{
|
||||
try
|
||||
{
|
||||
var doc = Autodesk.Navisworks.Api.Application.ActiveDocument;
|
||||
if (doc == null) return null;
|
||||
|
||||
var model = doc.Models.RootItemDescendants.FirstOrDefault(
|
||||
item => item.ToString() == id
|
||||
);
|
||||
|
||||
return model;
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
LogManager.Error($"查找模型项失败 (Id: {id}): {ex.Message}");
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
||||
@ -16,32 +16,34 @@ namespace NavisworksTransport.Core.Models
|
||||
public DateTime? StartTime { get; set; }
|
||||
public DateTime? EndTime { get; set; }
|
||||
public string ErrorMessage { get; set; }
|
||||
|
||||
|
||||
// 动画配置
|
||||
public int FrameRate { get; set; }
|
||||
public double DurationSeconds { get; set; }
|
||||
|
||||
|
||||
// 碰撞检测配置
|
||||
public double DetectionToleranceMeters { get; set; }
|
||||
|
||||
|
||||
// 运动物体配置
|
||||
public bool IsVirtualVehicle { get; set; }
|
||||
public double VirtualVehicleLength { get; set; }
|
||||
public double VirtualVehicleWidth { get; set; }
|
||||
public double VirtualVehicleHeight { get; set; }
|
||||
public string VehicleObjectId { get; set; }
|
||||
public string VehicleObjectName { get; set; }
|
||||
|
||||
// 被检测项
|
||||
public List<string> DetectionItems { get; set; } = new List<string>();
|
||||
|
||||
// 碰撞检测配置
|
||||
public bool DetectAllObjects { get; set; } = true;
|
||||
|
||||
|
||||
// 角度修正配置
|
||||
public double ObjectRotationCorrection { get; set; }
|
||||
|
||||
|
||||
// 结果
|
||||
public string ClashDetectiveTestName { get; set; }
|
||||
public int? CollisionCount { get; set; }
|
||||
|
||||
// 注意:运动物体和碰撞检测目标都存储在 ModelItemReferences 表中
|
||||
// 使用 BatchQueueItem.Id 作为 ReferenceId 进行查询
|
||||
// Role = "Vehicle" 表示运动物体
|
||||
// Role = "CollisionTarget" 表示碰撞检测目标
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
||||
@ -231,9 +231,9 @@ namespace NavisworksTransport
|
||||
VirtualVehicleLength REAL,
|
||||
VirtualVehicleWidth REAL,
|
||||
VirtualVehicleHeight REAL,
|
||||
VehicleObjectId TEXT,
|
||||
VehicleModelIndex INTEGER,
|
||||
VehiclePathId TEXT,
|
||||
VehicleObjectName TEXT,
|
||||
DetectionItems TEXT,
|
||||
DetectAllObjects INTEGER NOT NULL DEFAULT 1,
|
||||
ClashDetectiveTestName TEXT,
|
||||
CollisionCount INTEGER,
|
||||
@ -245,6 +245,23 @@ namespace NavisworksTransport
|
||||
ExecuteNonQuery("CREATE INDEX IF NOT EXISTS idx_batch_queue_status ON BatchQueueItems(Status)");
|
||||
ExecuteNonQuery("CREATE INDEX IF NOT EXISTS idx_batch_queue_created ON BatchQueueItems(CreatedTime)");
|
||||
ExecuteNonQuery("CREATE INDEX IF NOT EXISTS idx_batch_queue_path ON BatchQueueItems(PathRouteId)");
|
||||
|
||||
// 通用 ModelItem 引用表(用于存储运动物体、碰撞物体等)
|
||||
ExecuteNonQuery(@"
|
||||
CREATE TABLE IF NOT EXISTS ModelItemReferences (
|
||||
Id INTEGER PRIMARY KEY AUTOINCREMENT,
|
||||
ReferenceId INTEGER NOT NULL,
|
||||
ReferenceType TEXT NOT NULL,
|
||||
ModelIndex INTEGER NOT NULL,
|
||||
PathId TEXT NOT NULL,
|
||||
DisplayName TEXT,
|
||||
ObjectName TEXT,
|
||||
Role TEXT
|
||||
)
|
||||
");
|
||||
ExecuteNonQuery("CREATE INDEX IF NOT EXISTS idx_model_ref_reference ON ModelItemReferences(ReferenceId)");
|
||||
ExecuteNonQuery("CREATE INDEX IF NOT EXISTS idx_model_ref_type ON ModelItemReferences(ReferenceType)");
|
||||
ExecuteNonQuery("CREATE INDEX IF NOT EXISTS idx_model_ref_path ON ModelItemReferences(PathId)");
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@ -1358,18 +1375,18 @@ namespace NavisworksTransport
|
||||
PathRouteId, PathRouteName, Status, CreatedTime, StartTime, EndTime, ErrorMessage,
|
||||
FrameRate, DurationSeconds, DetectionToleranceMeters,
|
||||
IsVirtualVehicle, VirtualVehicleLength, VirtualVehicleWidth, VirtualVehicleHeight,
|
||||
VehicleObjectId, VehicleObjectName, DetectionItems, DetectAllObjects,
|
||||
DetectAllObjects,
|
||||
ClashDetectiveTestName, CollisionCount, ObjectRotationCorrection
|
||||
)
|
||||
VALUES (
|
||||
@PathRouteId, @PathRouteName, @Status, @CreatedTime, @StartTime, @EndTime, @ErrorMessage,
|
||||
@FrameRate, @DurationSeconds, @DetectionToleranceMeters,
|
||||
@IsVirtualVehicle, @VirtualVehicleLength, @VirtualVehicleWidth, @VirtualVehicleHeight,
|
||||
@VehicleObjectId, @VehicleObjectName, @DetectionItems, @DetectAllObjects,
|
||||
@DetectAllObjects,
|
||||
@ClashDetectiveTestName, @CollisionCount, @ObjectRotationCorrection
|
||||
);
|
||||
SELECT last_insert_rowid();";
|
||||
|
||||
|
||||
cmd.Parameters.AddWithValue("@PathRouteId", item.PathRouteId);
|
||||
cmd.Parameters.AddWithValue("@PathRouteName", item.PathRouteName ?? "");
|
||||
cmd.Parameters.AddWithValue("@Status", item.Status.ToString());
|
||||
@ -1384,15 +1401,19 @@ namespace NavisworksTransport
|
||||
cmd.Parameters.AddWithValue("@VirtualVehicleLength", item.VirtualVehicleLength);
|
||||
cmd.Parameters.AddWithValue("@VirtualVehicleWidth", item.VirtualVehicleWidth);
|
||||
cmd.Parameters.AddWithValue("@VirtualVehicleHeight", item.VirtualVehicleHeight);
|
||||
cmd.Parameters.AddWithValue("@VehicleObjectId", item.VehicleObjectId ?? "");
|
||||
cmd.Parameters.AddWithValue("@VehicleObjectName", item.VehicleObjectName ?? "");
|
||||
cmd.Parameters.AddWithValue("@DetectionItems", item.DetectionItems != null ? string.Join(",", item.DetectionItems) : "");
|
||||
cmd.Parameters.AddWithValue("@DetectAllObjects", item.DetectAllObjects ? 1 : 0);
|
||||
cmd.Parameters.AddWithValue("@ClashDetectiveTestName", item.ClashDetectiveTestName ?? "");
|
||||
cmd.Parameters.AddWithValue("@CollisionCount", item.CollisionCount ?? (object)DBNull.Value);
|
||||
cmd.Parameters.AddWithValue("@ObjectRotationCorrection", item.ObjectRotationCorrection);
|
||||
|
||||
return Convert.ToInt32(cmd.ExecuteScalar());
|
||||
|
||||
var queueItemId = Convert.ToInt32(cmd.ExecuteScalar());
|
||||
|
||||
// 注意:运动物体和碰撞检测目标都存储在 ModelItemReferences 表中
|
||||
// 这些数据在调用 CreateBatchQueueItemAsync 之前插入
|
||||
// Role = "Vehicle" 表示运动物体
|
||||
// Role = "CollisionTarget" 表示碰撞检测目标
|
||||
|
||||
return queueItemId;
|
||||
}
|
||||
});
|
||||
}
|
||||
@ -1411,7 +1432,7 @@ namespace NavisworksTransport
|
||||
SELECT Id, PathRouteId, PathRouteName, Status, CreatedTime, StartTime, EndTime, ErrorMessage,
|
||||
FrameRate, DurationSeconds, DetectionToleranceMeters,
|
||||
IsVirtualVehicle, VirtualVehicleLength, VirtualVehicleWidth, VirtualVehicleHeight,
|
||||
VehicleObjectId, VehicleObjectName, DetectionItems, DetectAllObjects,
|
||||
DetectAllObjects,
|
||||
ClashDetectiveTestName, CollisionCount, ObjectRotationCorrection
|
||||
FROM BatchQueueItems";
|
||||
var conditions = new List<string>();
|
||||
@ -1465,9 +1486,6 @@ namespace NavisworksTransport
|
||||
VirtualVehicleLength = Convert.ToDouble(reader["VirtualVehicleLength"]),
|
||||
VirtualVehicleWidth = Convert.ToDouble(reader["VirtualVehicleWidth"]),
|
||||
VirtualVehicleHeight = Convert.ToDouble(reader["VirtualVehicleHeight"]),
|
||||
VehicleObjectId = reader["VehicleObjectId"].ToString(),
|
||||
VehicleObjectName = reader["VehicleObjectName"].ToString(),
|
||||
DetectionItems = reader["DetectionItems"].ToString() != "" ? reader["DetectionItems"].ToString().Split(',').ToList() : new List<string>(),
|
||||
DetectAllObjects = Convert.ToBoolean(reader["DetectAllObjects"]),
|
||||
ClashDetectiveTestName = reader["ClashDetectiveTestName"].ToString(),
|
||||
CollisionCount = !Convert.IsDBNull(reader["CollisionCount"]) ? (int?)Convert.ToInt32(reader["CollisionCount"]) : null,
|
||||
@ -1493,18 +1511,18 @@ namespace NavisworksTransport
|
||||
SELECT Id, PathRouteId, PathRouteName, Status, CreatedTime, StartTime, EndTime, ErrorMessage,
|
||||
FrameRate, DurationSeconds, DetectionToleranceMeters,
|
||||
IsVirtualVehicle, VirtualVehicleLength, VirtualVehicleWidth, VirtualVehicleHeight,
|
||||
VehicleObjectId, VehicleObjectName, DetectionItems, DetectAllObjects,
|
||||
DetectAllObjects,
|
||||
ClashDetectiveTestName, CollisionCount, ObjectRotationCorrection
|
||||
FROM BatchQueueItems
|
||||
WHERE Id = @Id";
|
||||
|
||||
|
||||
cmd.Parameters.AddWithValue("@Id", itemId);
|
||||
|
||||
|
||||
using (var reader = cmd.ExecuteReader())
|
||||
{
|
||||
if (reader.Read())
|
||||
{
|
||||
return new BatchQueueItem
|
||||
var item = new BatchQueueItem
|
||||
{
|
||||
Id = Convert.ToInt32(reader["Id"]),
|
||||
PathRouteId = reader["PathRouteId"].ToString(),
|
||||
@ -1521,14 +1539,13 @@ namespace NavisworksTransport
|
||||
VirtualVehicleLength = Convert.ToDouble(reader["VirtualVehicleLength"]),
|
||||
VirtualVehicleWidth = Convert.ToDouble(reader["VirtualVehicleWidth"]),
|
||||
VirtualVehicleHeight = Convert.ToDouble(reader["VirtualVehicleHeight"]),
|
||||
VehicleObjectId = reader["VehicleObjectId"].ToString(),
|
||||
VehicleObjectName = reader["VehicleObjectName"].ToString(),
|
||||
DetectionItems = reader["DetectionItems"].ToString() != "" ? reader["DetectionItems"].ToString().Split(',').ToList() : new List<string>(),
|
||||
DetectAllObjects = Convert.ToBoolean(reader["DetectAllObjects"]),
|
||||
ClashDetectiveTestName = reader["ClashDetectiveTestName"].ToString(),
|
||||
CollisionCount = !Convert.IsDBNull(reader["CollisionCount"]) ? (int?)Convert.ToInt32(reader["CollisionCount"]) : null,
|
||||
ObjectRotationCorrection = Convert.ToDouble(reader["ObjectRotationCorrection"])
|
||||
};
|
||||
|
||||
return item;
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -1580,6 +1597,98 @@ namespace NavisworksTransport
|
||||
});
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 添加 ModelItem 引用到 ModelItemReferences 表
|
||||
/// </summary>
|
||||
public async Task<int> AddModelItemReferenceAsync(int referenceId, string referenceType, int modelIndex, string pathId, string displayName, string objectName, string role)
|
||||
{
|
||||
return await Task.Run(() =>
|
||||
{
|
||||
using (var cmd = new SQLiteCommand(_connection))
|
||||
{
|
||||
cmd.CommandText = @"
|
||||
INSERT INTO ModelItemReferences (ReferenceId, ReferenceType, ModelIndex, PathId, DisplayName, ObjectName, Role)
|
||||
VALUES (@ReferenceId, @ReferenceType, @ModelIndex, @PathId, @DisplayName, @ObjectName, @Role);
|
||||
SELECT last_insert_rowid();";
|
||||
|
||||
cmd.Parameters.AddWithValue("@ReferenceId", referenceId);
|
||||
cmd.Parameters.AddWithValue("@ReferenceType", referenceType);
|
||||
cmd.Parameters.AddWithValue("@ModelIndex", modelIndex);
|
||||
cmd.Parameters.AddWithValue("@PathId", pathId);
|
||||
cmd.Parameters.AddWithValue("@DisplayName", displayName ?? "");
|
||||
cmd.Parameters.AddWithValue("@ObjectName", objectName ?? "");
|
||||
cmd.Parameters.AddWithValue("@Role", role);
|
||||
|
||||
return Convert.ToInt32(cmd.ExecuteScalar());
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 获取指定 ReferenceId 和 Role 的所有 ModelItem 引用
|
||||
/// </summary>
|
||||
public async Task<List<(int ModelIndex, string PathId, string DisplayName, string ObjectName)>> GetModelItemReferencesAsync(int referenceId, string referenceType, string role = null)
|
||||
{
|
||||
return await Task.Run(() =>
|
||||
{
|
||||
var items = new List<(int, string, string, string)>();
|
||||
using (var cmd = new SQLiteCommand(_connection))
|
||||
{
|
||||
var sql = @"
|
||||
SELECT ModelIndex, PathId, DisplayName, ObjectName
|
||||
FROM ModelItemReferences
|
||||
WHERE ReferenceId = @ReferenceId AND ReferenceType = @ReferenceType";
|
||||
|
||||
if (!string.IsNullOrEmpty(role))
|
||||
{
|
||||
sql += " AND Role = @Role";
|
||||
cmd.Parameters.AddWithValue("@Role", role);
|
||||
}
|
||||
|
||||
cmd.CommandText = sql;
|
||||
cmd.Parameters.AddWithValue("@ReferenceId", referenceId);
|
||||
cmd.Parameters.AddWithValue("@ReferenceType", referenceType);
|
||||
|
||||
using (var reader = cmd.ExecuteReader())
|
||||
{
|
||||
while (reader.Read())
|
||||
{
|
||||
items.Add((
|
||||
Convert.ToInt32(reader["ModelIndex"]),
|
||||
reader["PathId"].ToString(),
|
||||
reader["DisplayName"].ToString(),
|
||||
reader["ObjectName"].ToString()
|
||||
));
|
||||
}
|
||||
}
|
||||
}
|
||||
return items;
|
||||
});
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 删除指定 ReferenceId 的所有 ModelItem 引用
|
||||
/// </summary>
|
||||
public async Task DeleteModelItemReferencesAsync(int referenceId, string referenceType = null)
|
||||
{
|
||||
await Task.Run(() =>
|
||||
{
|
||||
using (var cmd = new SQLiteCommand(_connection))
|
||||
{
|
||||
var sql = "DELETE FROM ModelItemReferences WHERE ReferenceId = @ReferenceId";
|
||||
if (!string.IsNullOrEmpty(referenceType))
|
||||
{
|
||||
sql += " AND ReferenceType = @ReferenceType";
|
||||
cmd.Parameters.AddWithValue("@ReferenceType", referenceType);
|
||||
}
|
||||
|
||||
cmd.CommandText = sql;
|
||||
cmd.Parameters.AddWithValue("@ReferenceId", referenceId);
|
||||
cmd.ExecuteNonQuery();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
/// <summary>
|
||||
|
||||
@ -2273,6 +2273,28 @@ namespace NavisworksTransport.UI.WPF.ViewModels
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 获取运动物体的 PathId 信息
|
||||
/// </summary>
|
||||
private (int ModelIndex, string PathId) GetVehiclePathIdInfo()
|
||||
{
|
||||
try
|
||||
{
|
||||
if (SelectedAnimatedObject == null)
|
||||
{
|
||||
return (0, null);
|
||||
}
|
||||
|
||||
var pathId = Application.ActiveDocument.Models.CreatePathId(SelectedAnimatedObject);
|
||||
return (pathId.ModelIndex, pathId.PathId);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
LogManager.Warning($"[批处理] 无法获取运动对象的 PathId: {SelectedAnimatedObject.DisplayName}, 错误: {ex.Message}");
|
||||
return (0, null);
|
||||
}
|
||||
}
|
||||
|
||||
private List<ModelItem> GetValidManualCollisionTargets(bool pruneInvalidEntries = false)
|
||||
{
|
||||
var validItems = new List<ModelItem>();
|
||||
@ -3528,7 +3550,7 @@ namespace NavisworksTransport.UI.WPF.ViewModels
|
||||
PathRouteName = CurrentPathRoute.Name,
|
||||
Status = BatchQueueStatus.Pending,
|
||||
CreatedTime = DateTime.Now,
|
||||
|
||||
|
||||
// 动画配置
|
||||
FrameRate = _animationFrameRate,
|
||||
DurationSeconds = AnimationDuration,
|
||||
@ -3541,39 +3563,81 @@ namespace NavisworksTransport.UI.WPF.ViewModels
|
||||
VirtualVehicleLength = VirtualVehicleLength,
|
||||
VirtualVehicleWidth = VirtualVehicleWidth,
|
||||
VirtualVehicleHeight = VirtualVehicleHeight,
|
||||
VehicleObjectId = UseVirtualVehicle ? null : SelectedAnimatedObject?.ToString(),
|
||||
VehicleObjectName = UseVirtualVehicle ? null : SelectedAnimatedObject?.DisplayName,
|
||||
|
||||
|
||||
// 被检测项配置
|
||||
DetectAllObjects = !IsManualCollisionTargetEnabled,
|
||||
DetectionItems = IsManualCollisionTargetEnabled
|
||||
? GetValidManualCollisionTargets(pruneInvalidEntries: true).Select(t => t.ToString()).ToList()
|
||||
: new List<string>(),
|
||||
|
||||
|
||||
// 角度修正配置
|
||||
ObjectRotationCorrection = _objectRotationCorrection
|
||||
};
|
||||
|
||||
// 调用批处理管理器添加到队列
|
||||
var batchQueueManager = Core.BatchQueueManager.Instance;
|
||||
|
||||
|
||||
// 确保BatchQueueManager有PathPlanningManager(用于获取数据库)
|
||||
if (_pathPlanningManager != null)
|
||||
{
|
||||
batchQueueManager.SetPathPlanningManager(_pathPlanningManager);
|
||||
}
|
||||
|
||||
|
||||
var itemId = await batchQueueManager.AddQueueItemAsync(queueItem);
|
||||
|
||||
|
||||
// 存储运动物体到 ModelItemReferences 表
|
||||
if (!UseVirtualVehicle && SelectedAnimatedObject != null)
|
||||
{
|
||||
var pathIdInfo = GetVehiclePathIdInfo();
|
||||
if (pathIdInfo.ModelIndex != 0 && !string.IsNullOrEmpty(pathIdInfo.PathId))
|
||||
{
|
||||
var db = _pathPlanningManager?.GetPathDatabase();
|
||||
if (db != null)
|
||||
{
|
||||
await db.AddModelItemReferenceAsync(
|
||||
itemId,
|
||||
"BatchQueueItem",
|
||||
pathIdInfo.ModelIndex,
|
||||
pathIdInfo.PathId,
|
||||
SelectedAnimatedObject.DisplayName,
|
||||
SelectedAnimatedObject.DisplayName,
|
||||
"Vehicle"
|
||||
);
|
||||
LogManager.Info($"[批处理] 已存储运动物体: {SelectedAnimatedObject.DisplayName}");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 存储手工指定的碰撞检测目标到 ModelItemReferences 表
|
||||
if (IsManualCollisionTargetEnabled)
|
||||
{
|
||||
var db = _pathPlanningManager?.GetPathDatabase();
|
||||
if (db != null)
|
||||
{
|
||||
var validItems = GetValidManualCollisionTargets(pruneInvalidEntries: true);
|
||||
foreach (var item in validItems)
|
||||
{
|
||||
var pathId = Application.ActiveDocument.Models.CreatePathId(item);
|
||||
await db.AddModelItemReferenceAsync(
|
||||
itemId,
|
||||
"BatchQueueItem",
|
||||
pathId.ModelIndex,
|
||||
pathId.PathId,
|
||||
item.DisplayName,
|
||||
item.DisplayName,
|
||||
"CollisionTarget"
|
||||
);
|
||||
}
|
||||
LogManager.Info($"[批处理] 已存储 {validItems.Count} 个手工指定碰撞目标");
|
||||
}
|
||||
}
|
||||
|
||||
LogManager.Info($"[批处理] 已创建队列项: {queueItem.PathRouteName}, " +
|
||||
$"虚拟车辆: {queueItem.IsVirtualVehicle}, " +
|
||||
$"帧率: {queueItem.FrameRate}, " +
|
||||
$"时长: {queueItem.DurationSeconds:F2}秒, " +
|
||||
$"角度修正: {queueItem.ObjectRotationCorrection:F1}°, " +
|
||||
$"ID: {itemId}");
|
||||
|
||||
|
||||
UpdateMainStatus($"已添加到批处理队列: {queueItem.PathRouteName}");
|
||||
|
||||
|
||||
// 显示成功提示
|
||||
System.Windows.MessageBox.Show(
|
||||
$"已成功添加到批处理队列:{queueItem.PathRouteName}\n" +
|
||||
@ -3586,7 +3650,7 @@ namespace NavisworksTransport.UI.WPF.ViewModels
|
||||
{
|
||||
LogManager.Error($"添加到批处理失败: {ex.Message}", ex);
|
||||
UpdateMainStatus($"添加失败: {ex.Message}");
|
||||
|
||||
|
||||
// 显示失败提示
|
||||
System.Windows.MessageBox.Show(
|
||||
$"添加到批处理队列失败:{ex.Message}",
|
||||
|
||||
@ -140,7 +140,7 @@ namespace NavisworksTransport.UI.WPF.ViewModels
|
||||
|
||||
// 初始化命令
|
||||
ExecuteQueueCommand = new RelayCommand(async () => await ExecuteQueueAsync(), () => CanExecuteQueue);
|
||||
StopExecutionCommand = new RelayCommand(StopExecution, () => CanStopExecution);
|
||||
StopExecutionCommand = new RelayCommand(StopExecution, () => true);
|
||||
DeleteItemCommand = new RelayCommand(async () => await DeleteItemAsync(), () => CanDeleteItem);
|
||||
ViewReportCommand = new RelayCommand(async () => await ViewReportAsync(), () => CanViewReport);
|
||||
RefreshCommand = new RelayCommand(async () => await LoadQueueItemsAsync());
|
||||
|
||||
@ -54,6 +54,7 @@ NavisworksTransport 批处理队列管理页签视图 - 采用与其他页签一
|
||||
Style="{StaticResource ActionButtonStyle}"/>
|
||||
<Button Content="停止执行"
|
||||
Command="{Binding StopExecutionCommand}"
|
||||
IsEnabled="True"
|
||||
Style="{StaticResource ActionButtonStyle}"/>
|
||||
<Button Content="删除选中"
|
||||
Command="{Binding DeleteItemCommand}"
|
||||
|
||||
Loading…
Reference in New Issue
Block a user