NavisworksTransport/src/Commands/CreateAerialPathCommand.cs

251 lines
10 KiB
C#
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

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
{
/// <summary>
/// 创建空中路径命令(空轨或吊装)
/// </summary>
public class CreateAerialPathCommand : CommandBase
{
private readonly AerialPathParameters _parameters;
private readonly PathPlanningManager _pathPlanningManager;
/// <summary>
/// 构造函数
/// </summary>
/// <param name="parameters">空中路径参数</param>
public CreateAerialPathCommand(AerialPathParameters parameters)
{
_parameters = parameters ?? throw new ArgumentNullException(nameof(parameters));
_pathPlanningManager = PathPlanningManager.Instance;
}
/// <summary>
/// 执行命令
/// </summary>
protected override Task<PathPlanningResult> ExecuteInternalAsync(CancellationToken cancellationToken)
{
try
{
// 验证参数
var validationResult = ValidateParameters();
if (!validationResult.IsSuccess)
{
return Task.FromResult<PathPlanningResult>(validationResult);
}
string pathTypeName = _parameters.PathType == PathType.Hoisting ? "吊装" : "空轨";
LogManager.Info($"开始创建{pathTypeName}路径...");
List<PathPoint> 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<PathRoute>.Success(route, $"{pathTypeName}路径创建成功");
return Task.FromResult<PathPlanningResult>(genericResult);
}
catch (Exception ex)
{
LogManager.Error($"创建空中路径失败: {ex.Message}", ex);
var genericResult = PathPlanningResult<PathRoute>.Failure($"创建空中路径失败: {ex.Message}", ex);
return Task.FromResult<PathPlanningResult>(genericResult);
}
}
/// <summary>
/// 验证参数
/// </summary>
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("参数验证通过");
}
/// <summary>
/// 从点击点生成空轨路径点(使用现有的空轨吸附逻辑)
/// </summary>
private List<PathPoint> GenerateRailPathPoints(List<Point3D> clickedPoints)
{
var pathPoints = new List<PathPoint>();
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;
}
}
/// <summary>
/// 空中路径参数
/// </summary>
public class AerialPathParameters
{
/// <summary>
/// 路径类型(空轨或吊装)
/// </summary>
public PathType PathType { get; set; }
/// <summary>
/// 吊装参数:起点(吊起位置)
/// </summary>
public Point3D StartPoint { get; set; }
/// <summary>
/// 吊装参数:终点(下降位置)
/// </summary>
public Point3D EndPoint { get; set; }
/// <summary>
/// 吊装参数:提升高度(米)
/// 单层吊装模式使用,多层模式下该值被忽略
/// </summary>
public double LiftHeightMeters { get; set; }
/// <summary>
/// 空轨参数:点击点列表
/// </summary>
public List<Point3D> ClickedPoints { get; set; }
/// <summary>
/// 吊装路径模式(默认单层,向后兼容)
/// </summary>
public HoistingMode HoistingMode { get; set; } = HoistingMode.SingleLevel;
/// <summary>
/// 多层吊装:层级信息列表(仅多层模式使用)
/// </summary>
public List<HoistingLevel> HoistingLevels { get; set; }
/// <summary>
/// 默认构造函数
/// </summary>
public AerialPathParameters()
{
HoistingMode = HoistingMode.SingleLevel;
HoistingLevels = new List<HoistingLevel>();
ClickedPoints = new List<Point3D>();
}
}
}