using System;
using System.Collections.Generic;
using System.Threading;
using System.Threading.Tasks;
using Autodesk.Navisworks.Api;
using NavisworksTransport.Core;
using NavisworksTransport.PathPlanning;
using NavisworksTransport.Utils;
using NavisworksTransport.Core.Config;
namespace NavisworksTransport.Commands
{
///
/// 创建空中路径命令(空轨或吊装)
///
public class CreateAerialPathCommand : CommandBase
{
private readonly AerialPathParameters _parameters;
private readonly PathPlanningManager _pathPlanningManager;
///
/// 构造函数
///
/// 空中路径参数
public CreateAerialPathCommand(AerialPathParameters parameters)
{
_parameters = parameters ?? throw new ArgumentNullException(nameof(parameters));
_pathPlanningManager = PathPlanningManager.Instance;
}
///
/// 执行命令
///
protected override Task ExecuteInternalAsync(CancellationToken cancellationToken)
{
try
{
// 验证参数
var validationResult = ValidateParameters();
if (!validationResult.IsSuccess)
{
return Task.FromResult(validationResult);
}
string pathTypeName = _parameters.PathType == PathType.Hoisting ? "吊装" : "空轨";
LogManager.Info($"开始创建{pathTypeName}路径...");
List pathPoints;
if (_parameters.PathType == PathType.Hoisting)
{
var generator = new AerialPathGenerator();
if (_parameters.HoistingMode == HoistingMode.MultiLevel &&
_parameters.HoistingLevels != null &&
_parameters.HoistingLevels.Count > 0)
{
// 多层阶梯式吊装
pathPoints = generator.GenerateMultiLevelHoistingPath(
_parameters.StartPoint,
_parameters.EndPoint,
_parameters.HoistingLevels);
LogManager.Info($"多层吊装路径: 起点=({_parameters.StartPoint.X:F2},{_parameters.StartPoint.Y:F2},{_parameters.StartPoint.Z:F2}), " +
$"终点=({_parameters.EndPoint.X:F2},{_parameters.EndPoint.Y:F2},{_parameters.EndPoint.Z:F2}), " +
$"层级数={_parameters.HoistingLevels.Count}, 总点数={pathPoints.Count}");
}
else
{
// 单层吊装(传统模式,默认)
double liftHeightModelUnits = UnitsConverter.ConvertFromMeters(_parameters.LiftHeightMeters);
pathPoints = generator.GenerateThreeStepHoistingPath(
_parameters.StartPoint,
_parameters.EndPoint,
liftHeightModelUnits);
LogManager.Info($"单层吊装路径: 起点=({_parameters.StartPoint.X:F2},{_parameters.StartPoint.Y:F2},{_parameters.StartPoint.Z:F2}), " +
$"终点=({_parameters.EndPoint.X:F2},{_parameters.EndPoint.Y:F2},{_parameters.EndPoint.Z:F2}), " +
$"提升高度={_parameters.LiftHeightMeters:F2}米");
}
}
else
{
// 空轨:使用现有的空轨吸附逻辑,从点击点生成路径点
pathPoints = GenerateRailPathPoints(_parameters.ClickedPoints);
LogManager.Info($"空轨路径: 路径点数={pathPoints.Count}");
}
// 创建路径对象
string routeName = _parameters.PathType == PathType.Hoisting
? $"吊装路径_{DateTime.Now:HHmmss}"
: $"空轨路径_{DateTime.Now:HHmmss}";
var route = new PathRoute(routeName)
{
PathType = _parameters.PathType,
LiftHeight = _parameters.PathType == PathType.Hoisting ? UnitsConverter.ConvertFromMeters(_parameters.LiftHeightMeters) : 0,
Points = pathPoints,
CreatedTime = DateTime.Now,
LastModified = DateTime.Now
};
// 设置物体参数(从配置获取,转换为模型单位)
var config = ConfigManager.Instance.Current;
route.MaxObjectLength = config.PathEditing.ObjectLength;
route.MaxObjectWidth = config.PathEditing.ObjectWidth;
route.MaxObjectHeight = config.PathEditing.ObjectHeight;
route.SafetyMargin = config.PathEditing.SafetyMargin;
// 注意:TotalLength 由计算属性实时提供,无需手动设置
// 它会自动从 Points 计算直线距离
LogManager.Info($"{pathTypeName}路径创建成功: {route.Name}, 路径点数: {pathPoints.Count}, 总长度: {route.TotalLength:F2}米");
// 保存路径到数据库
_pathPlanningManager.AddRoute(route);
var genericResult = PathPlanningResult.Success(route, $"{pathTypeName}路径创建成功");
return Task.FromResult(genericResult);
}
catch (Exception ex)
{
LogManager.Error($"创建空中路径失败: {ex.Message}", ex);
var genericResult = PathPlanningResult.Failure($"创建空中路径失败: {ex.Message}", ex);
return Task.FromResult(genericResult);
}
}
///
/// 验证参数
///
protected override PathPlanningResult ValidateParameters()
{
if (_parameters.PathType == PathType.Hoisting)
{
if (_parameters.StartPoint == null)
return PathPlanningResult.ValidationFailure("起点不能为空");
if (_parameters.EndPoint == null)
return PathPlanningResult.ValidationFailure("终点不能为空");
// 单层模式:检查 LiftHeightMeters
// 多层模式:检查 HoistingLevels
if (_parameters.HoistingMode == HoistingMode.SingleLevel)
{
if (_parameters.LiftHeightMeters <= 0)
return PathPlanningResult.ValidationFailure("提升高度必须大于0");
}
else if (_parameters.HoistingMode == HoistingMode.MultiLevel)
{
if (_parameters.HoistingLevels == null || _parameters.HoistingLevels.Count == 0)
return PathPlanningResult.ValidationFailure("请至少设置一个吊装层级");
// 检查每个层级的高度
foreach (var level in _parameters.HoistingLevels)
{
if (level.HeightInMeters <= 0)
return PathPlanningResult.ValidationFailure($"层级{level.Index + 1}的高度必须大于0");
}
}
}
else if (_parameters.PathType == PathType.Rail)
{
if (_parameters.ClickedPoints == null || _parameters.ClickedPoints.Count == 0)
return PathPlanningResult.ValidationFailure("点击点不能为空");
}
return PathPlanningResult.Success("参数验证通过");
}
///
/// 从点击点生成空轨路径点(使用现有的空轨吸附逻辑)
///
private List GenerateRailPathPoints(List clickedPoints)
{
var pathPoints = new List();
for (int i = 0; i < clickedPoints.Count; i++)
{
var point = clickedPoints[i];
var pointType = PathPointType.WayPoint;
if (i == 0)
pointType = PathPointType.StartPoint;
else if (i == clickedPoints.Count - 1)
pointType = PathPointType.EndPoint;
pathPoints.Add(new PathPoint(
point,
$"路径点{i + 1}",
pointType));
}
return pathPoints;
}
}
///
/// 空中路径参数
///
public class AerialPathParameters
{
///
/// 路径类型(空轨或吊装)
///
public PathType PathType { get; set; }
///
/// 吊装参数:起点(吊起位置)
///
public Point3D StartPoint { get; set; }
///
/// 吊装参数:终点(下降位置)
///
public Point3D EndPoint { get; set; }
///
/// 吊装参数:提升高度(米)
/// 单层吊装模式使用,多层模式下该值被忽略
///
public double LiftHeightMeters { get; set; }
///
/// 空轨参数:点击点列表
///
public List ClickedPoints { get; set; }
///
/// 吊装路径模式(默认单层,向后兼容)
///
public HoistingMode HoistingMode { get; set; } = HoistingMode.SingleLevel;
///
/// 多层吊装:层级信息列表(仅多层模式使用)
///
public List HoistingLevels { get; set; }
///
/// 默认构造函数
///
public AerialPathParameters()
{
HoistingMode = HoistingMode.SingleLevel;
HoistingLevels = new List();
ClickedPoints = new List();
}
}
}