优化单位转换的处理,使用缓存提高性能;控制米单位的使用
This commit is contained in:
parent
eeeaceacc4
commit
0d9eeed89b
@ -128,6 +128,34 @@ if (horizontalDirection != null)
|
||||
}
|
||||
```
|
||||
|
||||
### 起点终点延伸
|
||||
|
||||
为了确保通行空间完全包裹物体,所有水平段的起点和终点都需要向路径方向延伸半个物体尺寸:
|
||||
|
||||
```csharp
|
||||
// 通行空间包裹调整:水平段起点向反方向、终点向正方向各延伸半个物体尺寸
|
||||
if (_visualizationMode == PathVisualizationMode.VehicleSpace && !isVerticalSegment)
|
||||
{
|
||||
double offset = alongPathSize / 2.0; // 沿路径方向的物体尺寸的一半
|
||||
|
||||
// 起点向反方向延伸
|
||||
adjustedStartPoint = new Point3D(
|
||||
adjustedStartPoint.X - dirX * offset,
|
||||
adjustedStartPoint.Y - dirY * offset,
|
||||
adjustedStartPoint.Z - dirZ * offset
|
||||
);
|
||||
|
||||
// 终点向正方向延伸
|
||||
adjustedEndPoint = new Point3D(
|
||||
adjustedEndPoint.X + dirX * offset,
|
||||
adjustedEndPoint.Y + dirY * offset,
|
||||
adjustedEndPoint.Z + dirZ * offset
|
||||
);
|
||||
}
|
||||
```
|
||||
|
||||
**原因**:路径点使用物体中心坐标,如果不延伸,起点和终点处只会包裹物体的一半。
|
||||
|
||||
### 渲染模式
|
||||
|
||||
使用 `VehicleSpace` 可视化模式显示吊装路径的通行空间:
|
||||
@ -135,6 +163,7 @@ if (horizontalDirection != null)
|
||||
- 起吊/下降段:垂直长方体,截面为物体宽度 × 物体长度
|
||||
- 平移段(初始方向):水平长方体,截面为物体宽度 × 物体高度
|
||||
- 平移段(转折90度):水平长方体,截面为物体长度 × 物体高度
|
||||
- **所有水平段**:起点和终点向路径方向延伸半个物体尺寸,确保完全包裹
|
||||
|
||||
## 参考
|
||||
|
||||
|
||||
@ -473,6 +473,9 @@ namespace NavisworksTransport
|
||||
{
|
||||
LogManager.Info($"[文档管理] 文档已切换到: {NavisApplication.ActiveDocument?.FileName ?? "无活动文档"}");
|
||||
|
||||
// 清除单位转换缓存(文档切换后单位可能不同)
|
||||
Utils.UnitsConverter.ClearCache();
|
||||
|
||||
GlobalExceptionHandler.SafeExecute(() =>
|
||||
{
|
||||
var activeDoc = NavisApplication.ActiveDocument;
|
||||
|
||||
@ -389,14 +389,14 @@ namespace NavisworksTransport
|
||||
// 网格点类型配置
|
||||
private GridPointType _gridPointType = GridPointType.Rectangle;
|
||||
|
||||
// 通行空间参数(最终尺寸,已包括安全间隙)
|
||||
private double _passageAlongPath; // 通行空间沿路径方向的尺寸
|
||||
private double _passageAcrossPath; // 通行空间垂直于路径方向的尺寸
|
||||
private double _passageNormalToPath; // 通行空间法线方向的尺寸(垂直于路径和垂直于路径方向)
|
||||
// 通行空间参数(最终尺寸,已包括安全间隙)- 内部使用模型单位
|
||||
private double _passageAlongPath; // 通行空间沿路径方向的尺寸(模型单位)
|
||||
private double _passageAcrossPath; // 通行空间垂直于路径方向的尺寸(模型单位)
|
||||
private double _passageNormalToPath; // 通行空间法线方向的尺寸(模型单位)
|
||||
|
||||
// 物体尺寸(米)
|
||||
private double _objectLength; // 物体长度(米)
|
||||
private double _objectHeight; // 物体高度(米)
|
||||
// 物体尺寸 - 内部使用模型单位
|
||||
private double _objectLength; // 物体长度(模型单位)
|
||||
private double _objectHeight; // 物体高度(模型单位)
|
||||
|
||||
// 静态实例,用于外部访问
|
||||
private static PathPointRenderPlugin _instance;
|
||||
@ -1367,39 +1367,39 @@ namespace NavisworksTransport
|
||||
/// 计算通行空间参数(高度、宽度、颜色、透明度、垂直偏移)
|
||||
/// </summary>
|
||||
/// <param name="visualization">路径可视化对象</param>
|
||||
/// <param name="metersToModelUnits">米到模型单位的转换系数</param>
|
||||
/// <param name="isVerticalSegment">是否是垂直段(仅用于吊装路径)</param>
|
||||
/// <param name="isTurn90Horizontal">是否是与初始方向垂直的水平段(吊装路径转折90度)</param>
|
||||
/// <returns>通行空间参数元组</returns>
|
||||
private (double heightInModelUnits, double widthInModelUnits, Color lineColor, double lineOpacity, double verticalOffset)
|
||||
CalculatePassageSpaceParameters(PathVisualization visualization, double metersToModelUnits, bool isVerticalSegment = false, bool isTurn90Horizontal = false)
|
||||
private (double height, double width, Color lineColor, double lineOpacity, double verticalOffset)
|
||||
CalculatePassageSpaceParameters(PathVisualization visualization, bool isVerticalSegment = false, bool isTurn90Horizontal = false)
|
||||
{
|
||||
double heightInMeters;
|
||||
double widthInMeters;
|
||||
double height;
|
||||
double width;
|
||||
Color lineColor;
|
||||
double lineOpacity;
|
||||
|
||||
if (_visualizationMode == PathVisualizationMode.VehicleSpace)
|
||||
{
|
||||
// VehicleSpace 模式:根据路径类型和段类型计算通行空间尺寸
|
||||
// _passage* 和 _object* 字段已经是模型单位(由 SetPassageSpaceParameters 转换)
|
||||
if (visualization.PathRoute.PathType == NavisworksTransport.PathType.Hoisting)
|
||||
{
|
||||
// 吊装路径:根据段类型和方向设置尺寸
|
||||
// 默认:width=物体宽度(垂直于路径),height=物体高度/长度
|
||||
widthInMeters = _passageAcrossPath;
|
||||
heightInMeters = isVerticalSegment ? _objectLength : _objectHeight;
|
||||
width = _passageAcrossPath;
|
||||
height = isVerticalSegment ? _objectLength : _objectHeight;
|
||||
|
||||
// 🔥 水平段转折90度特殊处理:width改用物体长度
|
||||
if (!isVerticalSegment && isTurn90Horizontal)
|
||||
{
|
||||
widthInMeters = _objectLength;
|
||||
width = _objectLength;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// 其他路径类型
|
||||
widthInMeters = _passageAcrossPath;
|
||||
heightInMeters = _passageNormalToPath;
|
||||
width = _passageAcrossPath;
|
||||
height = _passageNormalToPath;
|
||||
}
|
||||
|
||||
var renderStyle = GetRenderStyle(RenderStyleName.VehicleSpace);
|
||||
@ -1409,8 +1409,9 @@ namespace NavisworksTransport
|
||||
else if (_visualizationMode == PathVisualizationMode.RibbonLine)
|
||||
{
|
||||
// RibbonLine 模式:使用较低的带状高度
|
||||
heightInMeters = GetLineRadius() / metersToModelUnits * 0.1;
|
||||
widthInMeters = _passageAcrossPath; // 使用通行空间垂直于路径方向的尺寸
|
||||
// GetLineRadius() 返回模型单位,直接乘以系数
|
||||
height = GetLineRadius() * 0.1;
|
||||
width = _passageAcrossPath; // 已经是模型单位
|
||||
var renderStyle = GetRenderStyle(RenderStyleName.Line);
|
||||
lineColor = renderStyle.Color;
|
||||
lineOpacity = renderStyle.Alpha;
|
||||
@ -1418,17 +1419,13 @@ namespace NavisworksTransport
|
||||
else
|
||||
{
|
||||
// StandardLine 模式:不需要高度和宽度(圆柱体)
|
||||
heightInMeters = 0;
|
||||
widthInMeters = 0;
|
||||
height = 0;
|
||||
width = 0;
|
||||
var renderStyle = GetRenderStyle(RenderStyleName.Line);
|
||||
lineColor = renderStyle.Color;
|
||||
lineOpacity = renderStyle.Alpha;
|
||||
}
|
||||
|
||||
// 转换为模型单位
|
||||
double heightInModelUnits = heightInMeters * metersToModelUnits;
|
||||
double widthInModelUnits = widthInMeters * metersToModelUnits;
|
||||
|
||||
// 计算通行空间的垂直偏移(根据路径类型)
|
||||
double verticalOffset = 0;
|
||||
if (_visualizationMode == PathVisualizationMode.VehicleSpace)
|
||||
@ -1436,12 +1433,12 @@ namespace NavisworksTransport
|
||||
if (visualization.PathRoute.PathType == NavisworksTransport.PathType.Ground)
|
||||
{
|
||||
// 地面路径:路径点是地面位置,通行空间底面在地面,中心需要向下偏移半个高度
|
||||
verticalOffset = -heightInModelUnits / 2.0;
|
||||
verticalOffset = -height / 2.0;
|
||||
}
|
||||
else if (visualization.PathRoute.PathType == NavisworksTransport.PathType.Rail)
|
||||
{
|
||||
// 空轨路径:路径点是轨道中心线位置,通行空间顶面对齐轨道,中心需要向上偏移半个高度
|
||||
verticalOffset = heightInModelUnits / 2.0;
|
||||
verticalOffset = height / 2.0;
|
||||
}
|
||||
else if (visualization.PathRoute.PathType == NavisworksTransport.PathType.Hoisting)
|
||||
{
|
||||
@ -1453,12 +1450,12 @@ namespace NavisworksTransport
|
||||
else
|
||||
{
|
||||
// 吊装的水平段:路径点是悬挂点位置,通行空间顶面在悬挂点,中心需要向上偏移半个高度
|
||||
verticalOffset = heightInModelUnits / 2.0;
|
||||
verticalOffset = height / 2.0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return (heightInModelUnits, widthInModelUnits, lineColor, lineOpacity, verticalOffset);
|
||||
return (height, width, lineColor, lineOpacity, verticalOffset);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@ -1502,8 +1499,8 @@ namespace NavisworksTransport
|
||||
double metersToModelUnits = UnitsConverter.GetMetersToUnitsConversionFactor();
|
||||
|
||||
// 计算通行空间参数
|
||||
var (heightInModelUnits, widthInModelUnits, lineColor, lineOpacity, verticalOffset) =
|
||||
CalculatePassageSpaceParameters(visualization, metersToModelUnits);
|
||||
var (height, width, lineColor, lineOpacity, verticalOffset) =
|
||||
CalculatePassageSpaceParameters(visualization);
|
||||
|
||||
// 3. 构建路径连线(Edges包含直线段和圆弧段)
|
||||
foreach (var edge in edges)
|
||||
@ -1545,6 +1542,9 @@ namespace NavisworksTransport
|
||||
adjustedEndPoint = endPoint;
|
||||
}
|
||||
|
||||
// 🔥 地面/空轨路径水平段:起点和终点向路径方向延伸半个物体尺寸
|
||||
ExtendLineSegmentForVehicleSpace(ref adjustedStartPoint, ref adjustedEndPoint, _passageAlongPath);
|
||||
|
||||
var lineMarker = new LineMarker
|
||||
{
|
||||
StartPoint = adjustedStartPoint,
|
||||
@ -1553,8 +1553,8 @@ namespace NavisworksTransport
|
||||
Radius = GetLineRadius(),
|
||||
SegmentType = PathSegmentType.Straight,
|
||||
SampledPoints = edge.SampledPoints,
|
||||
Height = heightInModelUnits, // 根据模式设置高度
|
||||
Width = widthInModelUnits, // 根据模式设置宽度
|
||||
Height = height, // 根据模式设置高度
|
||||
Width = width, // 根据模式设置宽度
|
||||
Opacity = lineOpacity // 根据模式设置透明度
|
||||
};
|
||||
visualization.PathLineMarkers.Add(lineMarker);
|
||||
@ -1625,6 +1625,9 @@ namespace NavisworksTransport
|
||||
adjustedSampledPoints = edge.SampledPoints;
|
||||
}
|
||||
|
||||
// 🔥 圆弧段:起点和终点向路径方向延伸半个物体尺寸
|
||||
ExtendLineSegmentForVehicleSpace(ref adjustedStartPoint, ref adjustedEndPoint, _passageAlongPath);
|
||||
|
||||
var arcMarker = new LineMarker
|
||||
{
|
||||
StartPoint = adjustedStartPoint,
|
||||
@ -1634,8 +1637,8 @@ namespace NavisworksTransport
|
||||
SegmentType = PathSegmentType.Arc,
|
||||
Trajectory = edge.Trajectory,
|
||||
SampledPoints = adjustedSampledPoints,
|
||||
Height = heightInModelUnits, // 根据模式设置高度
|
||||
Width = widthInModelUnits, // 根据模式设置宽度
|
||||
Height = height, // 根据模式设置高度
|
||||
Width = width, // 根据模式设置宽度
|
||||
Opacity = arcLineOpacity // 根据模式设置透明度
|
||||
};
|
||||
visualization.PathLineMarkers.Add(arcMarker);
|
||||
@ -1799,8 +1802,8 @@ namespace NavisworksTransport
|
||||
}
|
||||
}
|
||||
|
||||
var (heightInModelUnits, widthInModelUnits, lineColor, lineOpacity, verticalOffset) =
|
||||
CalculatePassageSpaceParameters(visualization, metersToModelUnits, isVerticalSegment, isTurn90Horizontal);
|
||||
var (height, width, lineColor, lineOpacity, verticalOffset) =
|
||||
CalculatePassageSpaceParameters(visualization, isVerticalSegment, isTurn90Horizontal);
|
||||
|
||||
// 计算长方体的轴向量(right和up向量)
|
||||
var (right, up) = CalculateCuboidAxes(startPoint.Position, endPoint.Position, horizontalDirection);
|
||||
@ -1831,67 +1834,17 @@ namespace NavisworksTransport
|
||||
adjustedEndPoint = endPoint.Position;
|
||||
}
|
||||
|
||||
// 暂时注释掉起点终点调整,先观察原始通行空间的误差
|
||||
/*
|
||||
// 通行空间模式下,调整起点和终点以包裹车辆
|
||||
if (_visualizationMode == PathVisualizationMode.VehicleSpace)
|
||||
// 🔥 通行空间包裹调整:水平段起点和终点延伸以完全包裹物体
|
||||
if (!isVerticalSegment)
|
||||
{
|
||||
bool needAdjust = false;
|
||||
if (visualization.PathRoute.PathType == NavisworksTransport.PathType.Ground)
|
||||
// 沿路径方向的物体尺寸(吊装路径根据是否转折90度选择)
|
||||
double alongPathSize = _passageAlongPath;
|
||||
if (visualization.PathRoute.PathType == NavisworksTransport.PathType.Hoisting)
|
||||
{
|
||||
needAdjust = true;
|
||||
}
|
||||
else if (visualization.PathRoute.PathType == NavisworksTransport.PathType.Rail)
|
||||
{
|
||||
needAdjust = true;
|
||||
}
|
||||
|
||||
if (needAdjust)
|
||||
{
|
||||
// 调整起点:沿起点→第二个点的方向后退半个车辆长度
|
||||
if (i == 0 && sortedPoints.Count >= 2)
|
||||
{
|
||||
var nextPoint = sortedPoints[1];
|
||||
var dx = nextPoint.Position.X - startPoint.Position.X;
|
||||
var dy = nextPoint.Position.Y - startPoint.Position.Y;
|
||||
var dz = nextPoint.Position.Z - startPoint.Position.Z;
|
||||
var length = Math.Sqrt(dx * dx + dy * dy + dz * dz);
|
||||
LogManager.Info($"[通行空间调整] 起点: 原点=({startPoint.Position.X:F3},{startPoint.Position.Y:F3},{startPoint.Position.Z:F3}), 方向=({dx:F3},{dy:F3},{dz:F3}), 长度={length:F3}, _passageAlongPath={_passageAlongPath:F3}");
|
||||
if (length > 0.001)
|
||||
{
|
||||
var offset = _passageAlongPath / 2.0;
|
||||
adjustedStartPoint = new Point3D(
|
||||
startPoint.Position.X - dx / length * offset,
|
||||
startPoint.Position.Y - dy / length * offset,
|
||||
startPoint.Position.Z - dz / length * offset + verticalOffset
|
||||
);
|
||||
LogManager.Info($"[通行空间调整] 调整后起点=({adjustedStartPoint.X:F3},{adjustedStartPoint.Y:F3},{adjustedStartPoint.Z:F3})");
|
||||
}
|
||||
}
|
||||
|
||||
// 调整终点:沿倒数第二个点→终点的方向前进半个车辆长度
|
||||
if (i == sortedPoints.Count - 2 && sortedPoints.Count >= 2)
|
||||
{
|
||||
var prevPoint = sortedPoints[i];
|
||||
var dx = endPoint.Position.X - prevPoint.Position.X;
|
||||
var dy = endPoint.Position.Y - prevPoint.Position.Y;
|
||||
var dz = endPoint.Position.Z - prevPoint.Position.Z;
|
||||
var length = Math.Sqrt(dx * dx + dy * dy + dz * dz);
|
||||
LogManager.Info($"[通行空间调整] 终点: 原点=({endPoint.Position.X:F3},{endPoint.Position.Y:F3},{endPoint.Position.Z:F3}), 方向=({dx:F3},{dy:F3},{dz:F3}), 长度={length:F3}, _passageAlongPath={_passageAlongPath:F3}");
|
||||
if (length > 0.001)
|
||||
{
|
||||
var offset = _passageAlongPath / 2.0;
|
||||
adjustedEndPoint = new Point3D(
|
||||
endPoint.Position.X + dx / length * offset,
|
||||
endPoint.Position.Y + dy / length * offset,
|
||||
endPoint.Position.Z + dz / length * offset + verticalOffset
|
||||
);
|
||||
LogManager.Info($"[通行空间调整] 调整后终点=({adjustedEndPoint.X:F3},{adjustedEndPoint.Y:F3},{adjustedEndPoint.Z:F3})");
|
||||
}
|
||||
}
|
||||
alongPathSize = isTurn90Horizontal ? _passageAcrossPath : _objectLength;
|
||||
}
|
||||
ExtendLineSegmentForVehicleSpace(ref adjustedStartPoint, ref adjustedEndPoint, alongPathSize);
|
||||
}
|
||||
*/
|
||||
|
||||
var lineMarker = new LineMarker
|
||||
{
|
||||
@ -1902,8 +1855,8 @@ namespace NavisworksTransport
|
||||
SegmentType = PathSegmentType.Straight,
|
||||
FromIndex = startPoint.Index,
|
||||
ToIndex = endPoint.Index,
|
||||
Height = heightInModelUnits,
|
||||
Width = widthInModelUnits,
|
||||
Height = height,
|
||||
Width = width,
|
||||
Opacity = lineOpacity,
|
||||
HorizontalDirection = horizontalDirection // 设置水平段方向向量
|
||||
};
|
||||
@ -2123,15 +2076,20 @@ namespace NavisworksTransport
|
||||
/// <param name="safetyMargin">安全间隙(米)</param>
|
||||
/// <param name="passageNormalToPathVertical">垂直段的高度(物体长度 + 2×安全间隙,模型单位)</param>
|
||||
/// <param name="passageNormalToPathHorizontal">水平段的高度(物体高度 + 2×安全间隙,模型单位)</param>
|
||||
public void SetPassageSpaceParameters(double passageAcrossPath, double passageNormalToPath, double passageAlongPath, double passageNormalToPathVertical = 0, double passageNormalToPathHorizontal = 0)
|
||||
/// <summary>
|
||||
/// 设置通行空间参数 - 外部传入米制单位,内部存储为模型单位
|
||||
/// </summary>
|
||||
public void SetPassageSpaceParameters(double passageAcrossPathInMeters, double passageNormalToPathInMeters, double passageAlongPathInMeters, double passageNormalToPathVerticalInMeters = 0, double passageNormalToPathHorizontalInMeters = 0)
|
||||
{
|
||||
_passageAlongPath = passageAlongPath; // 通行空间沿路径方向的尺寸(模型单位)
|
||||
_passageAcrossPath = passageAcrossPath; // 通行空间垂直于路径方向的尺寸(模型单位)
|
||||
_passageNormalToPath = passageNormalToPath; // 通行空间法线方向的尺寸(模型单位)
|
||||
// 转换为模型单位存储
|
||||
double factor = UnitsConverter.GetMetersToUnitsConversionFactor();
|
||||
_passageAlongPath = passageAlongPathInMeters * factor;
|
||||
_passageAcrossPath = passageAcrossPathInMeters * factor;
|
||||
_passageNormalToPath = passageNormalToPathInMeters * factor;
|
||||
|
||||
// 保存垂直段和水平段的高度(用于吊装路径分段渲染)
|
||||
_objectLength = passageNormalToPathVertical; // 垂直段高度(模型单位)
|
||||
_objectHeight = passageNormalToPathHorizontal; // 水平段高度(模型单位)
|
||||
_objectLength = passageNormalToPathVerticalInMeters * factor;
|
||||
_objectHeight = passageNormalToPathHorizontalInMeters * factor;
|
||||
|
||||
// 参数改变时刷新所有普通路径(因为RibbonLine模式也使用车辆宽度)
|
||||
RefreshNormalPaths();
|
||||
@ -2534,9 +2492,9 @@ namespace NavisworksTransport
|
||||
double metersToModelUnits = UnitsConverter.GetMetersToUnitsConversionFactor();
|
||||
|
||||
// 转换为模型单位
|
||||
double radiusInModelUnits = baseRadiusInMeters * metersToModelUnits;
|
||||
double radius = baseRadiusInMeters * metersToModelUnits;
|
||||
|
||||
return radiusInModelUnits;
|
||||
return radius;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@ -3030,6 +2988,44 @@ namespace NavisworksTransport
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 延伸线段起点和终点以完全包裹物体(VehicleSpace模式)
|
||||
/// </summary>
|
||||
/// <param name="startPoint">起点(会被修改)</param>
|
||||
/// <param name="endPoint">终点(会被修改)</param>
|
||||
private void ExtendLineSegmentForVehicleSpace(ref Point3D startPoint, ref Point3D endPoint, double alongPathSize)
|
||||
{
|
||||
if (_visualizationMode != PathVisualizationMode.VehicleSpace)
|
||||
return;
|
||||
|
||||
var segDx = endPoint.X - startPoint.X;
|
||||
var segDy = endPoint.Y - startPoint.Y;
|
||||
var segDz = endPoint.Z - startPoint.Z;
|
||||
var segLength = Math.Sqrt(segDx * segDx + segDy * segDy + segDz * segDz);
|
||||
|
||||
if (segLength > 0.001)
|
||||
{
|
||||
double offset = alongPathSize / 2.0;
|
||||
var dirX = segDx / segLength;
|
||||
var dirY = segDy / segLength;
|
||||
var dirZ = segDz / segLength;
|
||||
|
||||
// 起点向反方向延伸
|
||||
startPoint = new Point3D(
|
||||
startPoint.X - dirX * offset,
|
||||
startPoint.Y - dirY * offset,
|
||||
startPoint.Z - dirZ * offset
|
||||
);
|
||||
|
||||
// 终点向正方向延伸
|
||||
endPoint = new Point3D(
|
||||
endPoint.X + dirX * offset,
|
||||
endPoint.Y + dirY * offset,
|
||||
endPoint.Z + dirZ * offset
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 请求视图刷新(带防抖机制)
|
||||
/// </summary>
|
||||
|
||||
@ -153,7 +153,7 @@ namespace NavisworksTransport.PathPlanning
|
||||
private delegate float SpeedCalculator(
|
||||
int currentX, int currentY, int currentLayerIndex, double currentZ,
|
||||
int neighborX, int neighborY, int neighborLayerIndex, double neighborZ,
|
||||
double heightDiff, double baseSpeed, double maxHeightDiffInModelUnits,
|
||||
double heightDiff, double baseSpeed, double maxHeightDiff,
|
||||
Point3D startPos, Point3D endPos);
|
||||
|
||||
/// <summary>
|
||||
@ -170,10 +170,9 @@ namespace NavisworksTransport.PathPlanning
|
||||
double baseSpeed = 5.0; // km/h
|
||||
float maxSpeed = (float)baseSpeed;
|
||||
|
||||
// 将米转换为模型单位
|
||||
double maxHeightDiffMeters = GetMaxHeightDiffMeters();
|
||||
double maxHeightDiffInModelUnits = maxHeightDiffMeters * UnitsConverter.GetMetersToUnitsConversionFactor();
|
||||
LogManager.Info($"[3D图构建] 高度差阈值: {maxHeightDiffMeters}米 = {maxHeightDiffInModelUnits:F2}模型单位");
|
||||
// 使用配置的模型单位值
|
||||
double maxHeightDiff = ConfigManager.Instance.Current.PathEditing.MaxHeightDiff;
|
||||
LogManager.Info($"[3D图构建] 高度差阈值: {ConfigManager.Instance.Current.PathEditing.MaxHeightDiffMeters}米 = {maxHeightDiff:F2}模型单位");
|
||||
|
||||
// === 阶段1:创建所有3D节点 ===
|
||||
int totalNodesCreated = 0;
|
||||
@ -268,7 +267,7 @@ namespace NavisworksTransport.PathPlanning
|
||||
continue;
|
||||
|
||||
double heightDiff = Math.Abs(neighborLayer.Z - currentZ);
|
||||
if (heightDiff > maxHeightDiffInModelUnits)
|
||||
if (heightDiff > maxHeightDiff)
|
||||
continue;
|
||||
|
||||
if (!nodes.TryGetValue((nx, ny, nli), out var neighborNode))
|
||||
@ -279,11 +278,11 @@ namespace NavisworksTransport.PathPlanning
|
||||
if (speedCalculator != null)
|
||||
{
|
||||
speed = speedCalculator(x, y, li, currentZ, nx, ny, nli, neighborLayer.Z,
|
||||
heightDiff, baseSpeed, maxHeightDiffInModelUnits, startPos, endPos);
|
||||
heightDiff, baseSpeed, maxHeightDiff, startPos, endPos);
|
||||
}
|
||||
else
|
||||
{
|
||||
speed = CalculateSpeedByHeightDiff(heightDiff, baseSpeed, maxHeightDiffInModelUnits);
|
||||
speed = CalculateSpeedByHeightDiff(heightDiff, baseSpeed, maxHeightDiff);
|
||||
}
|
||||
|
||||
maxSpeed = Math.Max(maxSpeed, speed);
|
||||
@ -337,7 +336,7 @@ namespace NavisworksTransport.PathPlanning
|
||||
continue;
|
||||
|
||||
double heightDiff = Math.Abs(layer2.Z - layer1.Z);
|
||||
if (heightDiff > maxHeightDiffInModelUnits)
|
||||
if (heightDiff > maxHeightDiff)
|
||||
continue;
|
||||
|
||||
if (!nodes.TryGetValue((x2, y2, li), out var node1) ||
|
||||
@ -1607,15 +1606,14 @@ namespace NavisworksTransport.PathPlanning
|
||||
// 1. 起终点高度差不能超过阈值(原有逻辑:防止跨越大高度差,例如楼梯)
|
||||
// 2. 中间点高度必须与起点和终点一致(新增逻辑:任何高度变化都不能优化掉)
|
||||
bool canSkip = false;
|
||||
double maxAllowedHeightDiffMeters = GetMaxHeightDiffMeters(); // 从配置文件读取高度差阈值
|
||||
double maxAllowedHeightDiffInModelUnits = maxAllowedHeightDiffMeters * UnitsConverter.GetMetersToUnitsConversionFactor();
|
||||
double maxAllowedHeightDiff = ConfigManager.Instance.Current.PathEditing.MaxHeightDiff; // 从配置文件读取高度差阈值(模型单位)
|
||||
|
||||
double startZ = startPoint.Z;
|
||||
double endZ = endPoint.Z;
|
||||
double totalHeightDiff = Math.Abs(endZ - startZ);
|
||||
|
||||
// 检查1:起终点高度差必须在阈值内
|
||||
if (totalHeightDiff <= maxAllowedHeightDiffInModelUnits)
|
||||
if (totalHeightDiff <= maxAllowedHeightDiff)
|
||||
{
|
||||
// 检查2:所有中间点的高度必须与起点和终点一致(不能有高度变化)
|
||||
bool hasMiddleHeightChange = false;
|
||||
|
||||
@ -157,10 +157,9 @@ namespace NavisworksTransport.PathPlanning
|
||||
|
||||
// 2.7. 标记边界层(用于膨胀计算)
|
||||
LogManager.Info("【生成网格地图】步骤2.7: 标记边界层");
|
||||
double maxHeightDiffMeters = GetMaxHeightDiffMeters();
|
||||
double maxHeightDiffInModelUnits = maxHeightDiffMeters * metersToModelUnitsConversionFactor;
|
||||
LogManager.Info($"【生成网格地图】边界高度差阈值: {maxHeightDiffMeters}米 = {maxHeightDiffInModelUnits:F2}模型单位");
|
||||
MarkBoundaryLayers(channelCoverage.GridMap, maxHeightDiffInModelUnits);
|
||||
double maxHeightDiff = ConfigManager.Instance.Current.PathEditing.MaxHeightDiff;
|
||||
LogManager.Info($"【生成网格地图】边界高度差阈值: {ConfigManager.Instance.Current.PathEditing.MaxHeightDiffMeters}米 = {maxHeightDiff:F2}模型单位");
|
||||
MarkBoundaryLayers(channelCoverage.GridMap, maxHeightDiff);
|
||||
LogManager.Info($"【阶段2.7完成】边界层标记后网格统计: {channelCoverage.GridMap.GetStatistics()}");
|
||||
|
||||
// 3. 应用车辆尺寸膨胀
|
||||
@ -867,9 +866,7 @@ namespace NavisworksTransport.PathPlanning
|
||||
LogManager.Info($"【多层膨胀】开始按层处理膨胀,网格大小: {gridMap.Width}x{gridMap.Height}, 膨胀半径: {inflationRadius}");
|
||||
|
||||
// 计算高度差阈值(用于楼梯口保护)
|
||||
double metersToModelUnitsConversionFactor = UnitsConverter.GetMetersToUnitsConversionFactor(Application.ActiveDocument.Units);
|
||||
double maxHeightDiffMeters = GetMaxHeightDiffMeters();
|
||||
double maxHeightDiffInModelUnits = maxHeightDiffMeters * metersToModelUnitsConversionFactor;
|
||||
double maxHeightDiff = ConfigManager.Instance.Current.PathEditing.MaxHeightDiff;
|
||||
|
||||
// 统计每个层索引的处理情况
|
||||
var layerStats = new Dictionary<int, (int obstacleInflated, int boundaryCount, int boundaryInflated)>();
|
||||
@ -897,7 +894,7 @@ namespace NavisworksTransport.PathPlanning
|
||||
int obstacleInflated = InflateObstacles(gridMap, layerIndex, inflationRadius);
|
||||
|
||||
// 步骤2:边界膨胀(包括边界本身)
|
||||
var (boundaryCount, boundaryInflated) = InflateBoundaries(gridMap, layerIndex, inflationRadius, maxHeightDiffInModelUnits);
|
||||
var (boundaryCount, boundaryInflated) = InflateBoundaries(gridMap, layerIndex, inflationRadius, maxHeightDiff);
|
||||
|
||||
if (boundaryCount > 0 || obstacleInflated > 0)
|
||||
{
|
||||
|
||||
@ -6,25 +6,77 @@ namespace NavisworksTransport.Utils
|
||||
/// <summary>
|
||||
/// Navisworks单位转换工具类
|
||||
/// 提供统一的单位转换功能,避免代码重复
|
||||
///
|
||||
/// 性能优化:缓存转换系数,避免重复访问API
|
||||
/// </summary>
|
||||
public static class UnitsConverter
|
||||
{
|
||||
// 缓存字段 - 使用 NaN 作为初始值,避免默认值掩盖错误
|
||||
private static double _cachedUnitsToMetersFactor = double.NaN;
|
||||
private static double _cachedMetersToUnitsFactor = double.NaN;
|
||||
private static Units _cachedUnits = Units.Meters;
|
||||
|
||||
/// <summary>
|
||||
/// 清除转换系数缓存(在单位变化时调用)
|
||||
/// </summary>
|
||||
public static void ClearCache()
|
||||
{
|
||||
_cachedUnitsToMetersFactor = double.NaN;
|
||||
_cachedMetersToUnitsFactor = double.NaN;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 检查缓存是否有效(已设置且单位未变化)
|
||||
/// </summary>
|
||||
private static bool IsCacheValid()
|
||||
{
|
||||
// 从未设置过(NaN)
|
||||
if (double.IsNaN(_cachedUnitsToMetersFactor) || double.IsNaN(_cachedMetersToUnitsFactor))
|
||||
return false;
|
||||
|
||||
try
|
||||
{
|
||||
var currentUnits = Application.ActiveDocument?.Units ?? Units.Meters;
|
||||
return currentUnits == _cachedUnits;
|
||||
}
|
||||
catch
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 更新缓存
|
||||
/// </summary>
|
||||
private static void UpdateCache()
|
||||
{
|
||||
try
|
||||
{
|
||||
var currentUnits = Application.ActiveDocument?.Units ?? Units.Meters;
|
||||
|
||||
// 如果单位变化,更新缓存
|
||||
if (currentUnits != _cachedUnits)
|
||||
{
|
||||
_cachedUnits = currentUnits;
|
||||
_cachedUnitsToMetersFactor = GetUnitsToMetersConversionFactor(currentUnits);
|
||||
_cachedMetersToUnitsFactor = GetMetersToUnitsConversionFactor(currentUnits);
|
||||
}
|
||||
}
|
||||
catch (Exception)
|
||||
{
|
||||
// 出错时保留上次的有效值(如果有),否则保持 NaN 以暴露错误
|
||||
// 不要设置默认值,避免掩盖问题
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 获取Navisworks文档单位转换为米的系数
|
||||
/// </summary>
|
||||
/// <returns>转换系数(文档单位转换为米)</returns>
|
||||
public static double GetUnitsToMetersConversionFactor()
|
||||
{
|
||||
try
|
||||
{
|
||||
var units = Application.ActiveDocument.Units;
|
||||
return GetUnitsToMetersConversionFactor(units);
|
||||
}
|
||||
catch (Exception)
|
||||
{
|
||||
// 默认为米
|
||||
return 1.0;
|
||||
}
|
||||
UpdateCache();
|
||||
return _cachedUnitsToMetersFactor;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@ -69,16 +121,8 @@ namespace NavisworksTransport.Utils
|
||||
/// <returns>转换系数(米转换为文档单位)</returns>
|
||||
public static double GetMetersToUnitsConversionFactor()
|
||||
{
|
||||
try
|
||||
{
|
||||
var units = Application.ActiveDocument.Units;
|
||||
return GetMetersToUnitsConversionFactor(units);
|
||||
}
|
||||
catch (Exception)
|
||||
{
|
||||
// 默认为米
|
||||
return 1.0;
|
||||
}
|
||||
UpdateCache();
|
||||
return _cachedMetersToUnitsFactor;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@ -137,4 +181,4 @@ namespace NavisworksTransport.Utils
|
||||
return distanceInMeters * GetMetersToUnitsConversionFactor();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Loading…
Reference in New Issue
Block a user