diff --git a/src/Core/PathPlanningManager.cs b/src/Core/PathPlanningManager.cs
index b197b70..f37662d 100644
--- a/src/Core/PathPlanningManager.cs
+++ b/src/Core/PathPlanningManager.cs
@@ -1689,47 +1689,46 @@ namespace NavisworksTransport
{
LogManager.Info($"[吊装路径] 正在完成吊装路径,处理终点和下降点");
- // 确保至少有起吊点、提升点和至少一个空中路径点
- if (CurrentRoute.Points.Count >= 3 && _hoistingGroundIntermediatePoints.Count > 0)
+ // 确保至少有起吊点、提升点
+ if (CurrentRoute.Points.Count >= 2)
{
// 获取起吊点(用于获取地面Z坐标)
var startPoint = CurrentRoute.Points.First();
- // 获取吊装高度(内部使用模型单位,如果未设置则默认3米)
- double liftHeightModelUnits = CurrentRoute.LiftHeight > 0 ? CurrentRoute.LiftHeight : UnitsConverter.ConvertFromMeters(3.0);
+ // 获取最后一个路径点(用于获取当前的空中XY位置)
+ var lastPoint = CurrentRoute.Points.Last();
+ LogManager.Info($"[吊装路径] 最后一个路径点: {lastPoint.Name}, 位置: ({lastPoint.Position.X:F2}, {lastPoint.Position.Y:F2}, {lastPoint.Position.Z:F2})");
- // 获取最后一个地面点击点(原始坐标,未被调整过)
- var lastGroundClick = _hoistingGroundIntermediatePoints.Last();
- LogManager.Debug($"[吊装路径] 最后一个地面点击点: ({lastGroundClick.X:F2}, {lastGroundClick.Y:F2}, {lastGroundClick.Z:F2})");
+ // 计算下一个索引
+ int nextIndex = CurrentRoute.Points.Count;
- // 删除最后一个空中路径点(它的坐标可能被调整过,不使用任何信息)
- CurrentRoute.Points.RemoveAt(CurrentRoute.Points.Count - 1);
-
- // 创建落地点(终点):使用最后一个地面点击点的完整原始坐标(X、Y、Z)
- var endPoint = new PathPoint(
- new Point3D(lastGroundClick.X, lastGroundClick.Y, lastGroundClick.Z),
- "落地点",
- PathPointType.EndPoint);
- endPoint.Direction = HoistingPointDirection.Vertical;
- LogManager.Debug($"[吊装路径] 已创建落地点(终点): ({endPoint.Position.X:F2}, {endPoint.Position.Y:F2}, {endPoint.Position.Z:F2})");
-
- // 向上生成下降点:在落地点正上方,Z坐标为吊装高度
+ // 创建下降点:在落地点正上方,Z坐标为最后一个路径点的Z(保持当前高度)
var descendPoint = new PathPoint(
- new Point3D(endPoint.Position.X, endPoint.Position.Y, startPoint.Position.Z + liftHeightModelUnits),
+ new Point3D(lastPoint.Position.X, lastPoint.Position.Y, lastPoint.Position.Z),
"下降点",
PathPointType.WayPoint);
descendPoint.Direction = HoistingPointDirection.Vertical;
- LogManager.Debug($"[吊装路径] 已生成下降点(在终点正上方): ({descendPoint.Position.X:F2}, {descendPoint.Position.Y:F2}, {descendPoint.Position.Z:F2})");
+ descendPoint.Index = nextIndex++;
+ LogManager.Info($"[吊装路径] 已生成下降点(在终点正上方): ({descendPoint.Position.X:F2}, {descendPoint.Position.Y:F2}, {descendPoint.Position.Z:F2})");
+
+ // 创建落地点(终点):使用最后一个路径点的XY,使用起点Z作为地面高度
+ var endPoint = new PathPoint(
+ new Point3D(lastPoint.Position.X, lastPoint.Position.Y, startPoint.Position.Z),
+ "落地点",
+ PathPointType.EndPoint);
+ endPoint.Direction = HoistingPointDirection.Vertical;
+ endPoint.Index = nextIndex++;
+ LogManager.Info($"[吊装路径] 已创建落地点(终点): ({endPoint.Position.X:F2}, {endPoint.Position.Y:F2}, {endPoint.Position.Z:F2})");
// 添加下降点
CurrentRoute.Points.Add(descendPoint);
// 添加落地点(终点)
CurrentRoute.Points.Add(endPoint);
- LogManager.Debug($"[吊装路径] 已添加落地点(终点): ({endPoint.Position.X:F2}, {endPoint.Position.Y:F2}, {endPoint.Position.Z:F2})");
+ LogManager.Info($"[吊装路径] 已添加下降点和落地点,当前共 {CurrentRoute.Points.Count} 个路径点");
- // 优化路径点:处理斜线和清除多余点
- OptimizeRightAnglePathPoints(CurrentRoute);
+ // 注意:不需要再次调用 OrthogonalizePath,因为添加的只是垂直线段
+ // 垂直线段不会形成斜线,所以不需要优化
// 注意:TotalLength 现在是计算属性,自动从几何数据计算,无需手动更新
@@ -1921,6 +1920,7 @@ namespace NavisworksTransport
///
/// 检测两点之间是否为斜线,如果是则插入中间转折点或修正坐标
+ /// 处理三种斜线:XY平面斜线、XZ平面斜线、YZ平面斜线
///
/// 路径点列表
/// 开始检查的索引
@@ -1935,134 +1935,193 @@ namespace NavisworksTransport
var currentPoint = points[startIndex];
var nextPoint = points[startIndex + 1];
- LogManager.Debug($"[斜线处理] 检查索引 {startIndex} 和 {startIndex + 1} 之间的连线");
- LogManager.Debug($"[斜线处理] 当前点 [{startIndex}]: {currentPoint.Name}, 位置: ({currentPoint.Position.X:F2}, {currentPoint.Position.Y:F2}, {currentPoint.Position.Z:F2})");
- LogManager.Debug($"[斜线处理] 下一点 [{startIndex + 1}]: {nextPoint.Name}, 位置: ({nextPoint.Position.X:F2}, {nextPoint.Position.Y:F2}, {nextPoint.Position.Z:F2})");
+ // 使用 Info 级别日志以便调试
+ LogManager.Info($"[斜线处理] 检查索引 {startIndex} 和 {startIndex + 1} 之间的连线");
+ LogManager.Info($"[斜线处理] 当前点 [{startIndex}]: {currentPoint.Name}, 位置: ({currentPoint.Position.X:F2}, {currentPoint.Position.Y:F2}, {currentPoint.Position.Z:F2})");
+ LogManager.Info($"[斜线处理] 下一点 [{startIndex + 1}]: {nextPoint.Name}, 位置: ({nextPoint.Position.X:F2}, {nextPoint.Position.Y:F2}, {nextPoint.Position.Z:F2})");
double deltaX = Math.Abs(nextPoint.Position.X - currentPoint.Position.X);
double deltaY = Math.Abs(nextPoint.Position.Y - currentPoint.Position.Y);
+ double deltaZ = Math.Abs(nextPoint.Position.Z - currentPoint.Position.Z);
- // 检测斜线(X和Y都变化)
- bool isDiagonal = deltaX > 0.01 && deltaY > 0.01;
+ LogManager.Info($"[斜线处理] deltaX={deltaX:F2}, deltaY={deltaY:F2}, deltaZ={deltaZ:F2}");
- if (!isDiagonal)
+ // 检测三种斜线
+ bool isXYDiagonal = deltaX > 0.01 && deltaY > 0.01 && deltaZ < 0.001; // XY平面斜线
+ bool isXZDiagonal = deltaX > 0.01 && deltaZ > 0.001 && deltaY < 0.01; // XZ平面斜线
+ bool isYZDiagonal = deltaY > 0.01 && deltaZ > 0.001 && deltaX < 0.01; // YZ平面斜线
+ bool isXYZDiagonal = deltaX > 0.01 && deltaY > 0.01 && deltaZ > 0.001; // XYZ空间斜线
+
+ LogManager.Info($"[斜线处理] 斜线检测结果: XY={isXYDiagonal}, XZ={isXZDiagonal}, YZ={isYZDiagonal}, XYZ={isXYZDiagonal}");
+
+ if (!isXYDiagonal && !isXZDiagonal && !isYZDiagonal && !isXYZDiagonal)
{
+ LogManager.Info($"[斜线处理] 未检测到斜线,跳过处理");
return false;
}
- // 区分两种情况:
- // 1. 真正的斜线:deltaX和deltaY都比较大(>2.0)→ 插入中间点
- // 2. 微小偏差:其中一个值很小(<0.5)→ 修改下一点坐标,使其与上一点对齐
-
- if (deltaX > 2.0 && deltaY > 2.0)
+ // 处理XY平面斜线(水平斜线)
+ if (isXYDiagonal)
{
- // 真正的斜线:插入中间点
- LogManager.Debug($"[斜线处理] 检测到斜线,需要插入中间点 (deltaX={deltaX:F2}, deltaY={deltaY:F2})");
-
- int intermediateIndex = points.Count > 0 ? points.Count : 1;
- var intermediatePoint = new PathPoint(
- new Point3D(
- nextPoint.Position.X, // 使用新点的X
- currentPoint.Position.Y, // 保持上一个点的Y
- currentPoint.Position.Z // 保持吊装高度
- ),
- $"路径点{intermediateIndex}",
- PathPointType.WayPoint);
- intermediatePoint.Direction = HoistingPointDirection.Longitudinal; // 纵向移动
-
- int insertPosition = startIndex + 1;
- points.Insert(insertPosition, intermediatePoint);
-
- // 更新所有点的索引
- for (int i = 0; i < points.Count; i++)
- {
- points[i].Index = i;
- }
-
- LogManager.Debug($"[斜线处理] 已插入中间点: {intermediatePoint.Name}, 位置: ({intermediatePoint.Position.X:F2}, {intermediatePoint.Position.Y:F2}, {intermediatePoint.Position.Z:F2}) - 方向: 纵向");
- LogManager.Debug($"[斜线处理] 插入位置: 索引 {insertPosition}, 当前路径点总数: {points.Count}");
-
- return true;
+ return HandleXYDiagonal(points, startIndex, currentPoint, nextPoint, deltaX, deltaY);
}
- else if (deltaX < 0.5 && deltaY > 0.5)
+
+ // 处理XZ平面斜线(垂直斜线:X和Z同时变化)
+ if (isXZDiagonal)
{
- // X方向微小偏差,Y方向移动:修改下一点坐标,保持X与上一点对齐(垂直线)
- LogManager.Debug($"[斜线处理] 检测到X方向微小偏差 (deltaX={deltaX:F2}, deltaY={deltaY:F2}),修正下一点坐标使其垂直");
-
- nextPoint.Position = new Point3D(
- currentPoint.Position.X, // 保持上一个点的X
- nextPoint.Position.Y, // 保持新点的Y
- nextPoint.Position.Z); // 保持新点的Z
-
- LogManager.Debug($"[斜线处理] 已修正下一点 {nextPoint.Name} 坐标: ({nextPoint.Position.X:F2}, {nextPoint.Position.Y:F2}, {nextPoint.Position.Z:F2})");
- return true;
+ return HandleXZDiagonal(points, startIndex, currentPoint, nextPoint, deltaX, deltaZ);
}
- else if (deltaY < 0.5 && deltaX > 0.5)
+
+ // 处理YZ平面斜线(垂直斜线:Y和Z同时变化)
+ if (isYZDiagonal)
{
- // Y方向微小偏差,X方向移动:修改下一点坐标,保持Y与上一点对齐(水平线)
- LogManager.Debug($"[斜线处理] 检测到Y方向微小偏差 (deltaX={deltaX:F2}, deltaY={deltaY:F2}),修正下一点坐标使其水平");
-
- nextPoint.Position = new Point3D(
- nextPoint.Position.X, // 保持新点的X
- currentPoint.Position.Y, // 保持上一个点的Y
- nextPoint.Position.Z); // 保持新点的Z
-
- LogManager.Debug($"[斜线处理] 已修正下一点 {nextPoint.Name} 坐标: ({nextPoint.Position.X:F2}, {nextPoint.Position.Y:F2}, {nextPoint.Position.Z:F2})");
- return true;
+ return HandleYZDiagonal(points, startIndex, currentPoint, nextPoint, deltaY, deltaZ);
+ }
+
+ // 处理XYZ空间斜线(X、Y、Z都变化)
+ if (isXYZDiagonal)
+ {
+ return HandleXYZDiagonal(points, startIndex, currentPoint, nextPoint, deltaX, deltaY, deltaZ);
+ }
+
+ return false;
+ }
+
+ ///
+ /// 处理XY平面斜线(水平斜线)
+ /// 策略:插入中间点将斜线拆分为直角转折,保持用户点击的坐标不变
+ ///
+ private bool HandleXYDiagonal(IList points, int startIndex, PathPoint currentPoint, PathPoint nextPoint, double deltaX, double deltaY)
+ {
+ LogManager.Debug($"[斜线处理] 检测到XY平面斜线 (deltaX={deltaX:F2}, deltaY={deltaY:F2})");
+
+ // 策略:插入中间点,将斜线拆分为 X-only → Y-only 的两段直角路径
+ // 不修改用户点击的坐标,只插入转折点
+ // 转折点:X用新点的X,Y用旧点的Y(先X方向移动,再Y方向移动)
+ return InsertIntermediatePoint(points, startIndex, currentPoint, nextPoint,
+ new Point3D(nextPoint.Position.X, currentPoint.Position.Y, currentPoint.Position.Z),
+ HoistingPointDirection.Longitudinal);
+ }
+
+ ///
+ /// 处理XZ平面斜线(垂直斜线:X和Z同时变化)
+ /// 策略:先水平移动(X变化,Z不变),再垂直移动(Z变化,X不变)
+ ///
+ private bool HandleXZDiagonal(IList points, int startIndex, PathPoint currentPoint, PathPoint nextPoint, double deltaX, double deltaZ)
+ {
+ LogManager.Debug($"[斜线处理] 检测到XZ平面斜线 (deltaX={deltaX:F2}, deltaZ={deltaZ:F2})");
+
+ // 插入中间点:先水平移动(到新X,旧Z),目标点自然就是(新X,新Z)
+ return InsertIntermediatePoint(points, startIndex, currentPoint, nextPoint,
+ new Point3D(nextPoint.Position.X, currentPoint.Position.Y, currentPoint.Position.Z),
+ HoistingPointDirection.Longitudinal);
+ }
+
+ ///
+ /// 处理YZ平面斜线(垂直斜线:Y和Z同时变化)
+ /// 策略:先水平移动(Y变化,Z不变),再垂直移动(Z变化,Y不变)
+ ///
+ private bool HandleYZDiagonal(IList points, int startIndex, PathPoint currentPoint, PathPoint nextPoint, double deltaY, double deltaZ)
+ {
+ LogManager.Debug($"[斜线处理] 检测到YZ平面斜线 (deltaY={deltaY:F2}, deltaZ={deltaZ:F2})");
+
+ // 插入中间点:先水平移动(到新Y,旧Z),目标点自然就是(新Y,新Z)
+ return InsertIntermediatePoint(points, startIndex, currentPoint, nextPoint,
+ new Point3D(currentPoint.Position.X, nextPoint.Position.Y, currentPoint.Position.Z),
+ HoistingPointDirection.Lateral);
+ }
+
+ ///
+ /// 处理XYZ空间斜线(X、Y、Z都变化)
+ /// 策略:先水平移动(XY平面,Z不变),再垂直移动(Z变化,XY不变)
+ /// 水平移动时如果XY也是斜线,则进一步拆分
+ ///
+ private bool HandleXYZDiagonal(IList points, int startIndex, PathPoint currentPoint, PathPoint nextPoint, double deltaX, double deltaY, double deltaZ)
+ {
+ LogManager.Debug($"[斜线处理] 检测到XYZ空间斜线 (deltaX={deltaX:F2}, deltaY={deltaY:F2}, deltaZ={deltaZ:F2})");
+
+ // 分两步:
+ // 1. 先水平移动到目标XY(保持当前Z)
+ // 2. 再垂直移动到目标Z(保持XY不变)
+
+ // 如果水平移动也是斜线(X和Y都变化),则先处理XY斜线
+ if (deltaX > 0.01 && deltaY > 0.01)
+ {
+ // 插入中间点:先X方向移动(保持Y),到目标X后再处理Y和Z
+ return InsertIntermediatePoint(points, startIndex, currentPoint, nextPoint,
+ new Point3D(nextPoint.Position.X, currentPoint.Position.Y, currentPoint.Position.Z),
+ HoistingPointDirection.Longitudinal);
}
else
{
- // 中等程度的偏差,插入中间点
- LogManager.Debug($"[斜线处理] 检测到中等程度斜线,需要插入中间点 (deltaX={deltaX:F2}, deltaY={deltaY:F2})");
-
- int intermediateIndex = points.Count > 0 ? points.Count : 1;
- var intermediatePoint = new PathPoint(
- new Point3D(
- nextPoint.Position.X, // 使用新点的X
- currentPoint.Position.Y, // 保持上一个点的Y
- currentPoint.Position.Z // 保持吊装高度
- ),
- $"路径点{intermediateIndex}",
- PathPointType.WayPoint);
- intermediatePoint.Direction = HoistingPointDirection.Longitudinal; // 纵向移动
-
- int insertPosition = startIndex + 1;
- points.Insert(insertPosition, intermediatePoint);
-
- // 更新所有点的索引
- for (int i = 0; i < points.Count; i++)
+ // 水平方向只有一个轴变化,直接插入中间点处理垂直斜线
+ // 选择变化较大的水平轴作为先移动的方向
+ if (deltaX > deltaY)
{
- points[i].Index = i;
+ return InsertIntermediatePoint(points, startIndex, currentPoint, nextPoint,
+ new Point3D(nextPoint.Position.X, currentPoint.Position.Y, currentPoint.Position.Z),
+ HoistingPointDirection.Longitudinal);
+ }
+ else
+ {
+ return InsertIntermediatePoint(points, startIndex, currentPoint, nextPoint,
+ new Point3D(currentPoint.Position.X, nextPoint.Position.Y, currentPoint.Position.Z),
+ HoistingPointDirection.Lateral);
}
-
- LogManager.Debug($"[斜线处理] 已插入中间点: {intermediatePoint.Name}, 位置: ({intermediatePoint.Position.X:F2}, {intermediatePoint.Position.Y:F2}, {intermediatePoint.Position.Z:F2}) - 方向: 纵向");
- LogManager.Debug($"[斜线处理] 插入位置: 索引 {insertPosition}, 当前路径点总数: {points.Count}");
-
- return true;
}
}
///
- /// 优化直角转折路径点:出现斜线时插入点,在同一直线上时清除多余点
+ /// 插入中间点的辅助方法
///
- /// 要优化的路径
- /// 是否进行了优化
- public bool OptimizeRightAnglePathPoints(PathRoute route)
+ private bool InsertIntermediatePoint(IList points, int startIndex, PathPoint currentPoint, PathPoint nextPoint,
+ Point3D intermediatePosition, HoistingPointDirection direction)
+ {
+ int intermediateIndex = points.Count > 0 ? points.Count : 1;
+ var intermediatePoint = new PathPoint(intermediatePosition, $"路径点{intermediateIndex}", PathPointType.WayPoint);
+ intermediatePoint.Direction = direction;
+
+ int insertPosition = startIndex + 1;
+ points.Insert(insertPosition, intermediatePoint);
+
+ // 更新所有点的索引
+ for (int i = 0; i < points.Count; i++)
+ {
+ points[i].Index = i;
+ }
+
+ LogManager.Info($"[斜线处理] 已插入中间点: {intermediatePoint.Name}, 位置: ({intermediatePoint.Position.X:F2}, {intermediatePoint.Position.Y:F2}, {intermediatePoint.Position.Z:F2}) - 方向: {direction}");
+ LogManager.Info($"[斜线处理] 插入位置: 索引 {insertPosition}, 当前路径点总数: {points.Count}");
+
+ return true;
+ }
+
+ ///
+ /// 正交化路径:将斜线路径转换为轴对齐的直角路径
+ /// 出现斜线时插入转折点,使所有线段平行于X、Y或Z轴
+ ///
+ /// 要正交化的路径
+ /// 开始正交化的索引,默认从0开始(处理所有点)。用于增量处理,避免修改已处理的点。
+ /// 是否进行了正交化
+ public bool OrthogonalizePath(PathRoute route, int startIndex = 0)
{
if (route == null || route.Points.Count < 2)
{
return false;
}
+ // 确保startIndex有效
+ if (startIndex < 0) startIndex = 0;
+ if (startIndex >= route.Points.Count - 1) return false;
+
bool hasChanges = false;
var points = route.Points;
double tolerance = 0.001; // 容差,用于判断是否在同一直线上
- double smallDeviation = 0.5; // 微小偏差阈值,用于修正坐标
double minDistance = 1.0; // 最小距离阈值,小于此距离不删除点
// 第一步:处理斜线,插入转折点或修正坐标
- // 注意:由于可能插入点,需要从后往前遍历或使用while循环
- int i = 0;
+ // 从startIndex开始,只处理新添加的点
+ int i = startIndex;
while (i < points.Count - 1)
{
int originalCount = points.Count;
@@ -2074,7 +2133,7 @@ namespace NavisworksTransport
if (points.Count > originalCount)
{
// 插入了点,继续检查当前索引(因为插入点可能需要进一步优化)
- LogManager.Debug($"[直角路径优化] 索引{i}处插入了点,继续检查");
+ LogManager.Info($"[直角路径优化] 索引{i}处插入了点,继续检查");
}
else
{
@@ -2088,64 +2147,10 @@ namespace NavisworksTransport
}
}
- // 第二步:处理微小转折(X或Y方向微小偏差)
- for (i = 1; i < points.Count - 1; i++)
- {
- var prevPoint = points[i - 1];
- var currentPoint = points[i];
- var nextPoint = points[i + 1];
-
- // 计算两个方向的偏差
- double deltaX1 = Math.Abs(currentPoint.Position.X - prevPoint.Position.X);
- double deltaY1 = Math.Abs(currentPoint.Position.Y - prevPoint.Position.Y);
- double deltaX2 = Math.Abs(nextPoint.Position.X - currentPoint.Position.X);
- double deltaY2 = Math.Abs(nextPoint.Position.Y - currentPoint.Position.Y);
-
- // 检测微小转折:前一段和后一段都有微小偏差,但方向不同
- // 例如:前一段X变化很小,Y变化较大;后一段X变化较大,Y变化很小
- bool hasSmallTurn = false;
-
- // 前一段垂直,后一段水平
- if (deltaX1 < smallDeviation && deltaY1 > smallDeviation &&
- deltaY2 < smallDeviation && deltaX2 > smallDeviation)
- {
- hasSmallTurn = true;
- }
- // 前一段水平,后一段垂直
- else if (deltaY1 < smallDeviation && deltaX1 > smallDeviation &&
- deltaX2 < smallDeviation && deltaY2 > smallDeviation)
- {
- hasSmallTurn = true;
- }
-
- if (hasSmallTurn && currentPoint.Type == PathPointType.WayPoint)
- {
- // 修正转折点坐标,使其完全垂直
- if (deltaX1 < smallDeviation)
- {
- // 前一段垂直:调整转折点X与上一点对齐
- currentPoint.Position = new Point3D(
- prevPoint.Position.X,
- currentPoint.Position.Y,
- currentPoint.Position.Z);
- LogManager.Debug($"[直角路径优化] 修正微小转折点 {i} X坐标: ({currentPoint.Position.X:F2}, {currentPoint.Position.Y:F2}, {currentPoint.Position.Z:F2})");
- hasChanges = true;
- }
- else
- {
- // 前一段水平:调整转折点Y与上一点对齐
- currentPoint.Position = new Point3D(
- currentPoint.Position.X,
- prevPoint.Position.Y,
- currentPoint.Position.Z);
- LogManager.Debug($"[直角路径优化] 修正微小转折点 {i} Y坐标: ({currentPoint.Position.X:F2}, {currentPoint.Position.Y:F2}, {currentPoint.Position.Z:F2})");
- hasChanges = true;
- }
- }
- }
-
- // 第三步:清除在同一直线上的多余点
- i = 1;
+ // 第二步:清除在同一直线上的多余点
+ // 只检查从startIndex开始的新插入点,避免修改已处理的路径
+ int startForCollinear = Math.Max(1, startIndex);
+ i = startForCollinear;
while (i < points.Count - 1)
{
var prevPoint = points[i - 1];
@@ -2166,7 +2171,20 @@ namespace NavisworksTransport
continue;
}
- // 判断三个点是否在同一直线上(只检查X或Y方向相同)
+ // 判断三个点是否在同一直线上(需要在3D空间中共线)
+ // 首先检查Z坐标是否相同(在同一平面上)
+ double deltaZ1 = Math.Abs(currentPoint.Position.Z - prevPoint.Position.Z);
+ double deltaZ2 = Math.Abs(nextPoint.Position.Z - currentPoint.Position.Z);
+ bool sameZ = deltaZ1 < tolerance && deltaZ2 < tolerance;
+
+ // 如果Z不同,这三个点一定不共线(一个是垂直过渡点)
+ if (!sameZ)
+ {
+ i++;
+ continue;
+ }
+
+ // 在同一平面上,检查XY方向是否共线
bool sameX = Math.Abs(prevPoint.Position.X - currentPoint.Position.X) < tolerance &&
Math.Abs(currentPoint.Position.X - nextPoint.Position.X) < tolerance;
bool sameY = Math.Abs(prevPoint.Position.Y - currentPoint.Position.Y) < tolerance &&
@@ -2185,7 +2203,7 @@ namespace NavisworksTransport
// 删除中间点
points.RemoveAt(i);
hasChanges = true;
- LogManager.Debug($"[直角路径优化] 删除共线的多余点 {i}: ({currentPoint.Position.X:F2}, {currentPoint.Position.Y:F2}, {currentPoint.Position.Z:F2})");
+ LogManager.Info($"[直角路径优化] 删除共线的多余点 {i}: ({currentPoint.Position.X:F2}, {currentPoint.Position.Y:F2}, {currentPoint.Position.Z:F2})");
// 不调整索引,因为删除了一个点,新位置的点会在下一次循环被检查
continue;
@@ -2376,8 +2394,8 @@ namespace NavisworksTransport
UpdateAerialPathRelatedPoints(route, pointIndex);
}
- // 吊装路径:优化路径点(处理斜线和清除多余点)
- OptimizeRightAnglePathPoints(route);
+ // 吊装路径:正交化路径(处理斜线和清除多余点)
+ OrthogonalizePath(route);
}
else
{
@@ -2876,35 +2894,40 @@ namespace NavisworksTransport
return null;
}
- // 获取吊装高度(LiftHeight内部是模型单位,转换为米传给方法)
- double liftHeightMeters = CurrentRoute.LiftHeight > 0
- ? UnitsConverter.ConvertToMeters(CurrentRoute.LiftHeight)
- : 3.0;
+ // 获取吊装高度(LiftHeight内部是模型单位)
+ double liftHeightModelUnits = CurrentRoute.LiftHeight > 0
+ ? CurrentRoute.LiftHeight
+ : UnitsConverter.ConvertFromMeters(3.0);
// 使用 AerialPathGenerator 生成空中路径点
var generator = new AerialPathGenerator();
confirmPoint = generator.GenerateSmartHoistingPoint(
previousPoint,
_previewPoint.Position, // 用户点击的地面位置
- liftHeightMeters,
+ liftHeightModelUnits, // 直接使用模型单位
CurrentRoute.Points.Count > 0 ? CurrentRoute.Points.Count : 1);
LogManager.Info($"[预览点-吊装路径] 已生成空中路径点: {confirmPoint.Name}, 位置: ({confirmPoint.Position.X:F2}, {confirmPoint.Position.Y:F2}, {confirmPoint.Position.Z:F2})");
// 插入到正确位置
+ int optimizeStartIndex;
if (_previewInsertIndex >= 0 && _previewInsertIndex <= CurrentRoute.Points.Count)
{
CurrentRoute.InsertPoint(confirmPoint, _previewInsertIndex);
LogManager.Info($"[预览点-吊装路径] 已插入到索引 {_previewInsertIndex}");
+ // 从插入位置的前一个点开始优化
+ optimizeStartIndex = Math.Max(0, _previewInsertIndex - 1);
}
else
{
+ // 追加模式:记录添加前的点数
+ optimizeStartIndex = Math.Max(0, CurrentRoute.Points.Count - 1);
CurrentRoute.AddPoint(confirmPoint);
LogManager.Info($"[预览点-吊装路径] 已追加到末尾");
}
- // 调用路径优化方法处理斜线、微小转折和共线点
- OptimizeRightAnglePathPoints(CurrentRoute);
+ // 调用正交化方法处理斜线、微小转折和共线点(增量处理)
+ OrthogonalizePath(CurrentRoute, optimizeStartIndex);
LogManager.Info($"[预览点-吊装路径] 路径优化完成,当前路径点数: {CurrentRoute.Points.Count}");
}
else
@@ -3611,70 +3634,132 @@ namespace NavisworksTransport
}
else
{
- // 后续点击:添加空中路径点
- LogManager.Debug($"[吊装模式] 用户点击: ({clickedPoint.X:F2}, {clickedPoint.Y:F2}, {clickedPoint.Z:F2})");
+ // 后续点击:添加新的层级(每次都需要输入高度)
+ LogManager.Debug($"[吊装模式] 用户点击,准备添加新层级: ({clickedPoint.X:F2}, {clickedPoint.Y:F2}, {clickedPoint.Z:F2})");
- // 获取吊装高度(模型单位)
- double liftHeightModelUnits = _hoistingLiftHeight;
- if (liftHeightModelUnits <= 0)
+ // 记录地面点击位置,后续在UI线程中处理
+ Point3D groundPoint = clickedPoint;
+
+ // 在UI线程中弹出高度对话框并生成路径点
+ _uiStateManager.QueueUIUpdate(() =>
{
- liftHeightModelUnits = UnitsConverter.ConvertFromMeters(3.0);
- LogManager.Warning($"[吊装模式] 吊装高度无效,使用默认值: 3.0米");
- }
-
- // 使用 AerialPathGenerator 生成单个空中路径点(智能方向判断)
- try
- {
- var generator = new AerialPathGenerator();
-
- // 获取上一个路径点(用于方向判断)
- Point3D previousPoint;
- if (CurrentRoute.Points.Count > 0)
+ try
{
- // 如果已有路径点,使用最后一个路径点
- previousPoint = CurrentRoute.Points.Last().Position;
- }
- else
- {
- // 如果还没有路径点(第一次添加中间点),使用提升点
- previousPoint = new Point3D(
- _hoistingStartPoint.X,
- _hoistingStartPoint.Y,
- _hoistingStartPoint.Z + liftHeightModelUnits);
- }
+ // 计算默认高度(上一次的高度,如果没有则使用3米)
+ double defaultHeightMeters = _hoistingLiftHeight > 0
+ ? UnitsConverter.ConvertToMeters(_hoistingLiftHeight)
+ : 3.0;
+
+ var heightDialog = new NavisworksTransport.UI.WPF.Views.AerialHeightDialog(defaultHeight: defaultHeightMeters);
+ bool? dialogResult = heightDialog.ShowDialog();
- // 生成空中路径点
- var aerialPoint = generator.GenerateSmartHoistingPoint(
- previousPoint,
- clickedPoint,
- liftHeightModelUnits,
- CurrentRoute.Points.Count > 0 ? CurrentRoute.Points.Count : 1);
-
- if (aerialPoint != null)
- {
- // 保存上一个路径点的索引(用于插入中间点)
- int previousPointIndex = CurrentRoute.Points.Count - 1;
- var previousPathPoint = CurrentRoute.Points[previousPointIndex];
- LogManager.Debug($"[吊装模式] 上一个路径点索引: {previousPointIndex}, 名称: {previousPathPoint.Name}, 位置: ({previousPathPoint.Position.X:F2}, {previousPathPoint.Position.Y:F2})");
-
- // 记录原始地面点击位置
- _hoistingGroundIntermediatePoints.Add(clickedPoint);
- LogManager.Debug($"[吊装模式] 已记录地面点击点: ({clickedPoint.X:F2}, {clickedPoint.Y:F2}, {clickedPoint.Z:F2})");
-
- // 添加空中路径点(临时)
- CurrentRoute.AddPoint(aerialPoint);
- LogManager.Debug($"[吊装模式] 已添加空中路径点: {aerialPoint.Name}, 位置: ({aerialPoint.Position.X:F2}, {aerialPoint.Position.Y:F2}), 当前路径点数: {CurrentRoute.Points.Count}");
-
- // 调用路径优化方法处理斜线、微小转折和共线点
- OptimizeRightAnglePathPoints(CurrentRoute);
- LogManager.Debug($"[吊装模式] 路径优化完成,当前路径点数: {CurrentRoute.Points.Count}");
- for (int i = 0; i < CurrentRoute.Points.Count; i++)
+ // 如果用户取消,则只是跳过这次点击,继续等待下一次点击
+ if (dialogResult != true)
{
- var p = CurrentRoute.Points[i];
- LogManager.Debug($" [{i}] {p.Name}: ({p.Position.X:F2}, {p.Position.Y:F2}, {p.Position.Z:F2})");
+ LogManager.Info("[吊装模式] 用户取消了高度设置,继续等待点击");
+ RaiseStatusChanged("已取消,继续点击添加层级或点击完成按钮", PathPlanningStatusType.Info);
+ return;
}
- LogManager.Debug($"[吊装模式] 已添加空中路径点: {aerialPoint.Name} ({aerialPoint.Position.X:F2}, {aerialPoint.Position.Y:F2}, {aerialPoint.Position.Z:F2}) - 方向: {aerialPoint.Direction}");
+ // 检查用户是否选择"设为终点"(完成路径)
+ bool isSetAsEndPoint = heightDialog.IsSetAsEndPoint;
+
+ // 获取用户设置的高度
+ double liftHeightMetersInput = heightDialog.LiftHeightMeters;
+ double liftHeightModelUnits = UnitsConverter.ConvertFromMeters(liftHeightMetersInput);
+ double previousHeight = _hoistingLiftHeight;
+ _hoistingLiftHeight = liftHeightModelUnits;
+
+ // 更新路径的吊装高度(使用最新的高度)
+ if (CurrentRoute != null)
+ {
+ CurrentRoute.LiftHeight = liftHeightModelUnits;
+ }
+
+ LogManager.Info($"[吊装模式] 用户设置高度: {liftHeightMetersInput:F2}米,上一高度: {UnitsConverter.ConvertToMeters(previousHeight):F2}米");
+
+ // 获取上一个路径点
+ Point3D previousPoint;
+ if (CurrentRoute.Points.Count > 0)
+ {
+ previousPoint = CurrentRoute.Points.Last().Position;
+ var lastPoint = CurrentRoute.Points.Last();
+ LogManager.Info($"[吊装模式] 上一路径点: {lastPoint.Name}, Z={lastPoint.Position.Z:F2}");
+ }
+ else
+ {
+ previousPoint = new Point3D(
+ _hoistingStartPoint.X,
+ _hoistingStartPoint.Y,
+ _hoistingStartPoint.Z + liftHeightModelUnits);
+ LogManager.Info($"[吊装模式] 无上一路径点,使用起点+高度: Z={previousPoint.Z:F2}");
+ }
+
+ // 记录原始地面点击位置
+ _hoistingGroundIntermediatePoints.Add(groundPoint);
+ LogManager.Debug($"[吊装模式] 已记录地面点击点: ({groundPoint.X:F2}, {groundPoint.Y:F2}, {groundPoint.Z:F2})");
+
+ // 检查高度是否变化(比较绝对高度)
+ // liftHeightModelUnits 是相对地面的高度,需要加上起点Z得到绝对高度
+ double newAbsoluteHeight = _hoistingStartPoint.Z + liftHeightModelUnits;
+ double heightDiff = Math.Abs(newAbsoluteHeight - previousPoint.Z);
+ bool heightChanged = heightDiff > 0.001;
+
+ LogManager.Info($"[吊装模式] 起点=({_hoistingStartPoint.X:F2}, {_hoistingStartPoint.Y:F2}, {_hoistingStartPoint.Z:F2})");
+ LogManager.Info($"[吊装模式] 相对高度(米)={liftHeightMetersInput:F2}, 相对高度(模型)={liftHeightModelUnits:F2}");
+ LogManager.Info($"[吊装模式] 新绝对高度={newAbsoluteHeight:F2}, 上一位置Z={previousPoint.Z:F2}");
+
+ // 步骤1:水平移动点(在旧高度上移动到新XY)
+ // 使用 AerialPathGenerator 生成水平路径点
+ LogManager.Info($"[吊装模式] 生成水平路径点: previousPoint=({previousPoint.X:F2}, {previousPoint.Y:F2}, {previousPoint.Z:F2}), groundPoint=({groundPoint.X:F2}, {groundPoint.Y:F2}, {groundPoint.Z:F2})");
+
+ // 记录添加新点前的点数,用于增量优化
+ int pointCountBefore = CurrentRoute.Points.Count;
+
+ var generator = new AerialPathGenerator();
+ var aerialPoint = generator.GenerateSmartHoistingPoint(
+ previousPoint,
+ groundPoint,
+ previousPoint.Z, // 保持旧高度
+ CurrentRoute.Points.Count > 0 ? CurrentRoute.Points.Count : 1);
+
+ if (aerialPoint != null)
+ {
+ // 添加水平移动路径点
+ CurrentRoute.AddPoint(aerialPoint);
+ LogManager.Info($"[吊装模式] 已添加水平路径点: {aerialPoint.Name}, 位置: ({aerialPoint.Position.X:F2}, {aerialPoint.Position.Y:F2}, {aerialPoint.Position.Z:F2})");
+
+ // 更新上一个点为水平路径点
+ previousPoint = aerialPoint.Position;
+ }
+
+ // 步骤2:在添加垂直过渡点前,先正交化水平路径(此时所有点在同一高度,可以处理斜线)
+ // 使用增量处理,只处理新添加的点(从添加前最后一个点的索引开始)
+ int orthogonalizeStartIndex = Math.Max(0, pointCountBefore - 1);
+ OrthogonalizePath(CurrentRoute, orthogonalizeStartIndex);
+
+ // 步骤3:如果需要,添加垂直过渡点
+ if (heightChanged)
+ {
+ // 高度变化:垂直上升到新高度
+ LogManager.Info($"[吊装模式] 高度变化,插入垂直过渡点: Z={previousPoint.Z:F2} -> Z={newAbsoluteHeight:F2}");
+
+ var verticalTransitionPoint = new Point3D(
+ previousPoint.X,
+ previousPoint.Y,
+ newAbsoluteHeight);
+ var verticalPoint = new PathPoint(
+ verticalTransitionPoint,
+ $"高度过渡{CurrentRoute.Points.Count}",
+ PathPointType.WayPoint);
+ verticalPoint.Direction = HoistingPointDirection.Vertical;
+ CurrentRoute.AddPoint(verticalPoint);
+ LogManager.Info($"[吊装模式] 已添加垂直过渡点: ({verticalTransitionPoint.X:F2}, {verticalTransitionPoint.Y:F2}, {verticalTransitionPoint.Z:F2})");
+ }
+ else
+ {
+ LogManager.Info($"[吊装模式] 高度未变化,无需垂直过渡");
+ }
// 渲染路径
if (_renderPlugin != null)
@@ -3682,15 +3767,28 @@ namespace NavisworksTransport
_renderPlugin.RenderPath(CurrentRoute);
}
- // 提示用户可以继续添加或点击完成
- string directionText = aerialPoint.Direction == HoistingPointDirection.Longitudinal ? "纵向" : "横向";
- RaiseStatusChanged($"已添加{directionText}路径点,继续点击或点击完成按钮", PathPlanningStatusType.Info);
+ // 如果用户选择"设为终点",调用 FinishEditing 完成路径
+ if (isSetAsEndPoint)
+ {
+ LogManager.Info("[吊装模式] 用户选择设为终点,调用 FinishEditing 完成路径");
+ bool finished = FinishEditing();
+ if (finished && CurrentRoute != null)
+ {
+ // 触发路径列表更新事件,通知UI刷新
+ RaisePathPointsListUpdated(CurrentRoute, "设为终点完成路径");
+ }
+ }
+ else
+ {
+ string transitionText = heightChanged ? "(含高度过渡)" : "";
+ RaiseStatusChanged($"已添加层级路径点{transitionText}(高度: {liftHeightMetersInput:F2}米),继续点击添加新层级或点击完成按钮", PathPlanningStatusType.Info);
+ }
}
- }
- catch (Exception ex)
- {
- LogManager.Error($"[吊装模式] 生成空中路径点失败: {ex.Message}", ex);
- }
+ catch (Exception ex)
+ {
+ LogManager.Error($"[吊装模式] 添加层级失败: {ex.Message}", ex);
+ }
+ }, UIUpdatePriority.High);
return;
}
diff --git a/src/Core/PathPointRenderPlugin.cs b/src/Core/PathPointRenderPlugin.cs
index e7203c3..803b77b 100644
--- a/src/Core/PathPointRenderPlugin.cs
+++ b/src/Core/PathPointRenderPlugin.cs
@@ -1494,16 +1494,9 @@ namespace NavisworksTransport
}
else if (visualization.PathRoute.PathType == NavisworksTransport.PathType.Hoisting)
{
- if (isVerticalSegment)
- {
- // 吊装路径的垂直段(起吊段和下降段):通行空间底面在地面,不需要偏移
- verticalOffset = 0;
- }
- else
- {
- // 吊装的水平段:路径点是悬挂点位置,通行空间顶面在悬挂点,中心需要向上偏移半个高度
- verticalOffset = height / 2.0;
- }
+ // 吊装路径:物体顶面中心就是路径点,通行空间整体向下移动半个高度
+ // 这样通行空间顶面中心对齐路径点
+ verticalOffset = -height / 2.0;
}
}
@@ -1575,16 +1568,16 @@ namespace NavisworksTransport
if (_showObjectSpace && Math.Abs(verticalOffset) > 0.001)
{
- // 通行空间模式且有垂直偏移时,沿着up向量方向平移
+ // 通行空间模式且有垂直偏移时,沿Z轴平移(确保只有垂直偏移,没有水平偏移)
adjustedStartPoint = new Point3D(
- startPoint.X + up.X * verticalOffset,
- startPoint.Y + up.Y * verticalOffset,
- startPoint.Z + up.Z * verticalOffset
+ startPoint.X,
+ startPoint.Y,
+ startPoint.Z + verticalOffset
);
adjustedEndPoint = new Point3D(
- endPoint.X + up.X * verticalOffset,
- endPoint.Y + up.Y * verticalOffset,
- endPoint.Z + up.Z * verticalOffset
+ endPoint.X,
+ endPoint.Y,
+ endPoint.Z + verticalOffset
);
}
else
@@ -1646,28 +1639,28 @@ namespace NavisworksTransport
if (_showObjectSpace && Math.Abs(verticalOffset) > 0.001)
{
- // 通行空间模式且有垂直偏移时,沿着up向量方向平移
+ // 通行空间模式且有垂直偏移时,沿Z轴平移(确保只有垂直偏移,没有水平偏移)
adjustedStartPoint = new Point3D(
- startPoint.X + up.X * verticalOffset,
- startPoint.Y + up.Y * verticalOffset,
- startPoint.Z + up.Z * verticalOffset
+ startPoint.X,
+ startPoint.Y,
+ startPoint.Z + verticalOffset
);
adjustedEndPoint = new Point3D(
- endPoint.X + up.X * verticalOffset,
- endPoint.Y + up.Y * verticalOffset,
- endPoint.Z + up.Z * verticalOffset
+ endPoint.X,
+ endPoint.Y,
+ endPoint.Z + verticalOffset
);
- // 对 SampledPoints 应用垂直偏移(沿着up向量方向)
+ // 对 SampledPoints 应用垂直偏移(沿Z轴)
adjustedSampledPoints = new List();
if (edge.SampledPoints != null)
{
foreach (var point in edge.SampledPoints)
{
adjustedSampledPoints.Add(new Point3D(
- point.X + up.X * verticalOffset,
- point.Y + up.Y * verticalOffset,
- point.Z + up.Z * verticalOffset
+ point.X,
+ point.Y,
+ point.Z + verticalOffset
));
}
}
@@ -1873,17 +1866,37 @@ namespace NavisworksTransport
if (_showObjectSpace && Math.Abs(verticalOffset) > 0.001)
{
- // 通行空间模式且有垂直偏移时,沿着up向量方向平移
- adjustedStartPoint = new Point3D(
- startPoint.Position.X + up.X * verticalOffset,
- startPoint.Position.Y + up.Y * verticalOffset,
- startPoint.Position.Z + up.Z * verticalOffset
- );
- adjustedEndPoint = new Point3D(
- endPoint.Position.X + up.X * verticalOffset,
- endPoint.Position.Y + up.Y * verticalOffset,
- endPoint.Position.Z + up.Z * verticalOffset
- );
+ // 通行空间模式且有垂直偏移时
+ // 垂直空中路径:只沿Z轴偏移(没有水平偏移)
+ // 水平路径:沿up向量偏移(up是垂直的)
+ if (isVerticalSegment)
+ {
+ // 垂直段:只沿Z轴偏移
+ adjustedStartPoint = new Point3D(
+ startPoint.Position.X,
+ startPoint.Position.Y,
+ startPoint.Position.Z + verticalOffset
+ );
+ adjustedEndPoint = new Point3D(
+ endPoint.Position.X,
+ endPoint.Position.Y,
+ endPoint.Position.Z + verticalOffset
+ );
+ }
+ else
+ {
+ // 水平段:沿up向量偏移(up是垂直的)
+ adjustedStartPoint = new Point3D(
+ startPoint.Position.X + up.X * verticalOffset,
+ startPoint.Position.Y + up.Y * verticalOffset,
+ startPoint.Position.Z + up.Z * verticalOffset
+ );
+ adjustedEndPoint = new Point3D(
+ endPoint.Position.X + up.X * verticalOffset,
+ endPoint.Position.Y + up.Y * verticalOffset,
+ endPoint.Position.Z + up.Z * verticalOffset
+ );
+ }
}
else
{
@@ -2789,6 +2802,7 @@ namespace NavisworksTransport
// 直线段:单个长方体
// 设置颜色和透明度
graphics.Color(lineMarker.Color, lineMarker.Opacity);
+
RenderCuboidMarker(
graphics,
lineMarker.StartPoint,
diff --git a/src/PathPlanning/AerialPathGenerator.cs b/src/PathPlanning/AerialPathGenerator.cs
index 9502613..8130002 100644
--- a/src/PathPlanning/AerialPathGenerator.cs
+++ b/src/PathPlanning/AerialPathGenerator.cs
@@ -89,31 +89,30 @@ namespace NavisworksTransport.PathPlanning
///
/// 上一个路径点
/// 用户点击的地面投影位置
- /// 吊装高度(米)
+ /// 目标高度(模型单位)
/// 路径点序号
/// 生成的路径点
public PathPoint GenerateSmartHoistingPoint(
Point3D previousPoint,
Point3D clickedGroundPoint,
- double liftHeightMeters,
+ double targetHeightModelUnits,
int pointIndex)
{
if (previousPoint == null)
throw new ArgumentNullException(nameof(previousPoint));
if (clickedGroundPoint == null)
throw new ArgumentNullException(nameof(clickedGroundPoint));
- if (liftHeightMeters <= 0)
- throw new ArgumentException("提升高度必须大于0", nameof(liftHeightMeters));
+ // 注意:targetHeightModelUnits 是绝对高度,可以是负数(如果起点在地下)
// 计算两个方向的距离
double deltaX = Math.Abs(clickedGroundPoint.X - previousPoint.X);
double deltaY = Math.Abs(clickedGroundPoint.Y - previousPoint.Y);
- // 直接使用地面点的完整XY值,不调整位置
+ // 使用目标高度作为Z坐标,XY使用地面点击位置
Point3D newPoint = new Point3D(
clickedGroundPoint.X,
clickedGroundPoint.Y,
- previousPoint.Z); // 使用上一个路径点的Z坐标(保持吊装高度)
+ targetHeightModelUnits); // 使用传入的目标高度
// 判断移动方向(仅用于记录,不影响位置)
HoistingPointDirection direction;
@@ -195,7 +194,7 @@ namespace NavisworksTransport.PathPlanning
var newPoint = GenerateSmartHoistingPoint(
previousPoint,
groundIntermediatePoints[i],
- liftHeightMeters,
+ liftHeightModelUnits, // 使用模型单位的高度
i + 1);
pathPoints.Add(newPoint);
diff --git a/src/UI/WPF/ViewModels/PathEditingViewModel.cs b/src/UI/WPF/ViewModels/PathEditingViewModel.cs
index 669dd1f..b3d5746 100644
--- a/src/UI/WPF/ViewModels/PathEditingViewModel.cs
+++ b/src/UI/WPF/ViewModels/PathEditingViewModel.cs
@@ -2685,10 +2685,10 @@ namespace NavisworksTransport.UI.WPF.ViewModels
coreRoute.Points.Remove(corePoint);
LogManager.Info($"已从Core数据删除路径点: {corePoint.Name}");
- // 吊装路径:优化路径点(处理斜线和清除多余点)
+ // 吊装路径:正交化路径(处理斜线和清除多余点)
if (coreRoute.PathType == PathType.Hoisting)
{
- _pathPlanningManager?.OptimizeRightAnglePathPoints(coreRoute);
+ _pathPlanningManager?.OrthogonalizePath(coreRoute);
}
// 调用PathPlanningManager的3D删除方法
diff --git a/src/UI/WPF/Views/AerialHeightDialog.xaml b/src/UI/WPF/Views/AerialHeightDialog.xaml
index 02ba713..692a6d2 100644
--- a/src/UI/WPF/Views/AerialHeightDialog.xaml
+++ b/src/UI/WPF/Views/AerialHeightDialog.xaml
@@ -55,17 +55,28 @@
-
+ Margin="0,0,10,0"
+ ToolTip="设置高度并继续添加更多路径点"/>
+
+ Height="32"
+ ToolTip="取消这次点击"/>
diff --git a/src/UI/WPF/Views/AerialHeightDialog.xaml.cs b/src/UI/WPF/Views/AerialHeightDialog.xaml.cs
index 673b64d..4a991b9 100644
--- a/src/UI/WPF/Views/AerialHeightDialog.xaml.cs
+++ b/src/UI/WPF/Views/AerialHeightDialog.xaml.cs
@@ -13,6 +13,11 @@ namespace NavisworksTransport.UI.WPF.Views
///
public double LiftHeightMeters { get; private set; }
+ ///
+ /// 获取是否设为终点(完成路径)
+ ///
+ public bool IsSetAsEndPoint { get; private set; }
+
///
/// 构造函数
///
@@ -31,19 +36,26 @@ namespace NavisworksTransport.UI.WPF.Views
}
///
- /// 确定按钮点击事件
+ /// 确定按钮点击事件 - 添加层级(继续)
///
private void OnOKClick(object sender, RoutedEventArgs e)
{
- if (double.TryParse(HeightTextBox.Text, out double height) && height > 0)
+ if (ValidateHeight())
{
- LiftHeightMeters = height;
+ IsSetAsEndPoint = false;
DialogResult = true;
}
- else
+ }
+
+ ///
+ /// 设为终点按钮点击事件 - 完成路径
+ ///
+ private void OnSetAsEndPointClick(object sender, RoutedEventArgs e)
+ {
+ if (ValidateHeight())
{
- System.Windows.MessageBox.Show("请输入有效的提升高度(大于0的数字)", "错误",
- MessageBoxButton.OK, MessageBoxImage.Error);
+ IsSetAsEndPoint = true;
+ DialogResult = true;
}
}
@@ -54,5 +66,23 @@ namespace NavisworksTransport.UI.WPF.Views
{
DialogResult = false;
}
+
+ ///
+ /// 验证输入的高度是否有效
+ ///
+ private bool ValidateHeight()
+ {
+ if (double.TryParse(HeightTextBox.Text, out double height) && height > 0)
+ {
+ LiftHeightMeters = height;
+ return true;
+ }
+ else
+ {
+ System.Windows.MessageBox.Show("请输入有效的提升高度(大于0的数字)", "错误",
+ MessageBoxButton.OK, MessageBoxImage.Error);
+ return false;
+ }
+ }
}
}
\ No newline at end of file
diff --git a/src/UI/WPF/Views/PathEditingView.xaml b/src/UI/WPF/Views/PathEditingView.xaml
index 3cea8b0..9724bcd 100644
--- a/src/UI/WPF/Views/PathEditingView.xaml
+++ b/src/UI/WPF/Views/PathEditingView.xaml
@@ -213,11 +213,7 @@ NavisworksTransport 路径编辑页签视图 - 采用与动画控制和分层管
-
+ ToolTip="创建吊装路径(支持多层)"/>