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(); } } }