重构网格可视化功能,使用单独的结构和渲染方法

This commit is contained in:
tian 2026-01-16 21:06:20 +08:00
parent 07f8f5b2bf
commit 1813c9831d
4 changed files with 301 additions and 78 deletions

View File

@ -113,6 +113,7 @@
<Compile Include="src\Core\PathAnalysisService.cs" />
<Compile Include="src\Core\PathPlanningModels.cs" />
<Compile Include="src\Core\PathCurveEngine.cs" />
<Compile Include="src\Core\GridVisualization.cs" />
<!-- Core - Events and Interfaces -->
<Compile Include="src\Core\IPathPlanningManagerEvents.cs" />
<Compile Include="src\Core\PathPlanningManagerEventArgs.cs" />

View File

@ -0,0 +1,111 @@
using System.Collections.Generic;
using Autodesk.Navisworks.Api;
namespace NavisworksTransport
{
/// <summary>
/// 网格可视化类型(仅用于网格可视化,不用于数据模型)
/// </summary>
public enum GridVisualizationType
{
/// <summary>
/// 可通行通道(绿色)
/// </summary>
Walkable,
/// <summary>
/// 障碍物(灰色)
/// </summary>
Obstacle,
/// <summary>
/// 未知区域(红色)
/// </summary>
Unknown,
/// <summary>
/// 门(半透明绿色)
/// </summary>
Door
}
/// <summary>
/// 网格可视化标记点
/// </summary>
public class GridMarker
{
/// <summary>
/// 3D 位置
/// </summary>
public Point3D Position { get; set; }
/// <summary>
/// 网格可视化类型(可通行性)
/// </summary>
public GridVisualizationType CellType { get; set; }
/// <summary>
/// 网格坐标 X
/// </summary>
public int GridX { get; set; }
/// <summary>
/// 网格坐标 Y
/// </summary>
public int GridY { get; set; }
/// <summary>
/// 高度层 Z 坐标
/// </summary>
public double LayerZ { get; set; }
public GridMarker() { }
public GridMarker(Point3D position, GridVisualizationType cellType, int gridX, int gridY, double layerZ)
{
Position = position;
CellType = cellType;
GridX = gridX;
GridY = gridY;
LayerZ = layerZ;
}
}
/// <summary>
/// 网格可视化集合
/// </summary>
public class GridVisualization
{
/// <summary>
/// 可视化 ID
/// </summary>
public string Id { get; set; }
/// <summary>
/// 可通行的网格标记(绿色)
/// </summary>
public List<GridMarker> Walkable { get; } = new List<GridMarker>();
/// <summary>
/// 障碍物网格标记(灰色)
/// </summary>
public List<GridMarker> Obstacle { get; } = new List<GridMarker>();
/// <summary>
/// 未知区域网格标记(红色)
/// </summary>
public List<GridMarker> Unknown { get; } = new List<GridMarker>();
/// <summary>
/// 门网格标记(半透明绿色)
/// </summary>
public List<GridMarker> Door { get; } = new List<GridMarker>();
public GridVisualization() { }
public GridVisualization(string id)
{
Id = id;
}
}
}

View File

@ -3678,26 +3678,8 @@ namespace NavisworksTransport
// 清除之前的网格可视化
ClearGridVisualization();
// 创建四种独立的网格可视化路径
var channelRoute = new PathRoute("GridVisualization_Channel")
{
Id = "grid_visualization_channel"
};
var unknownRoute = new PathRoute("GridVisualization_Unknown")
{
Id = "grid_visualization_unknown"
};
var obstacleRoute = new PathRoute("GridVisualization_Obstacle")
{
Id = "grid_visualization_obstacle"
};
var doorRoute = new PathRoute("GridVisualization_Door")
{
Id = "grid_visualization_door"
};
// 创建网格可视化集合
var gridVis = new GridVisualization("grid_visualization");
// 统计变量
int channelCells = 0;
@ -3729,8 +3711,7 @@ namespace NavisworksTransport
{
double layerZ = layer.Z;
PathRoute targetRoute = null;
string gridTypeName = "";
GridVisualizationType? cellType = null;
// 仅根据 layer.IsWalkable 决定渲染
if (layer.IsWalkable)
@ -3740,8 +3721,7 @@ namespace NavisworksTransport
{
if (_showDoorGrid)
{
targetRoute = doorRoute;
gridTypeName = "门";
cellType = GridVisualizationType.Door;
doorCells++;
}
}
@ -3750,8 +3730,7 @@ namespace NavisworksTransport
// 其他可通行类型统一为通道样式(绿色)
if (_showWalkableGrid)
{
targetRoute = channelRoute;
gridTypeName = "通道";
cellType = GridVisualizationType.Walkable;
channelCells++;
}
}
@ -3761,27 +3740,33 @@ namespace NavisworksTransport
// 不可通行层 - 渲染为障碍物(灰色)
if (_showObstacleGrid)
{
targetRoute = obstacleRoute;
gridTypeName = "障碍";
cellType = GridVisualizationType.Obstacle;
obstacleCells++;
}
}
// 创建该层的可视化
if (targetRoute != null)
// 创建该层的可视化标记
if (cellType.HasValue)
{
var gridCenter = new Point3D(centerX, centerY, layerZ);
var marker = new GridMarker(gridCenter, cellType.Value, x, y, layerZ);
var gridPoint = new PathPoint
// 根据类型添加到对应列表
switch (cellType.Value)
{
Position = gridCenter,
Name = $"网格_{gridTypeName}({x},{y})_Z{layerZ:F2}",
Type = PathPointType.WayPoint,
Index = totalVisualized,
Notes = $"GridType:{cell.CellType}, LayerZ={layerZ:F2}, IsWalkable={layer.IsWalkable}"
};
targetRoute.Points.Add(gridPoint);
case GridVisualizationType.Walkable:
gridVis.Walkable.Add(marker);
break;
case GridVisualizationType.Obstacle:
gridVis.Obstacle.Add(marker);
break;
case GridVisualizationType.Unknown:
gridVis.Unknown.Add(marker);
break;
case GridVisualizationType.Door:
gridVis.Door.Add(marker);
break;
}
totalVisualized++;
}
}
@ -3792,15 +3777,8 @@ namespace NavisworksTransport
if (_showUnknownGrid)
{
var gridCenter = new Point3D(centerX, centerY, gridCorner.Z);
var gridPoint = new PathPoint
{
Position = gridCenter,
Name = $"网格_空洞({x},{y})",
Type = PathPointType.WayPoint,
Index = totalVisualized,
Notes = $"GridType:Unknown, NoLayers"
};
unknownRoute.Points.Add(gridPoint);
var marker = new GridMarker(gridCenter, GridVisualizationType.Unknown, x, y, gridCorner.Z);
gridVis.Unknown.Add(marker);
unknownCells++;
totalVisualized++;
}
@ -3808,30 +3786,8 @@ namespace NavisworksTransport
}
}
// 分别渲染四种类型的网格点
if (channelRoute.Points.Count > 0)
{
renderPlugin.RenderPointOnly(channelRoute);
LogManager.Info($"[网格可视化] 渲染可通行网格层: {channelRoute.Points.Count} 个(绿色)");
}
if (doorRoute.Points.Count > 0)
{
renderPlugin.RenderPointOnly(doorRoute);
LogManager.Info($"[网格可视化] 渲染门网格层: {doorRoute.Points.Count} 个50%透明绿色)");
}
if (unknownRoute.Points.Count > 0)
{
renderPlugin.RenderPointOnly(unknownRoute);
LogManager.Info($"[网格可视化] 渲染Unknown网格: {unknownRoute.Points.Count} 个(红色,调试用)");
}
if (obstacleRoute.Points.Count > 0)
{
renderPlugin.RenderPointOnly(obstacleRoute);
LogManager.Info($"[网格可视化] 渲染障碍物网格层: {obstacleRoute.Points.Count} 个(灰色)");
}
// 使用新的专门渲染方法(类型安全)
renderPlugin.RenderGridVisualization(gridVis);
// 输出统计信息
LogManager.Info($"[网格可视化] 可视化完成:");
@ -3864,12 +3820,14 @@ namespace NavisworksTransport
var renderPlugin = PathPointRenderPlugin.Instance;
if (renderPlugin != null)
{
// 清除所有网格可视化路径(包括旧的和新的)
renderPlugin.RemovePath("grid_visualization_all"); // 旧的单一路径
renderPlugin.RemovePath("grid_visualization_channel"); // 新的通道路径
renderPlugin.RemovePath("grid_visualization_unknown"); // 新的Unknown路径
renderPlugin.RemovePath("grid_visualization_obstacle"); // 新的障碍物路径
renderPlugin.RemovePath("grid_visualization_door"); // 新的门路径
// 清除所有网格可视化(使用新的 ID 命名)
renderPlugin.RemovePath("grid_visualization_walkable"); // 可通行的网格
renderPlugin.RemovePath("grid_visualization_obstacle"); // 障碍物网格
renderPlugin.RemovePath("grid_visualization_unknown"); // 未知区域网格
renderPlugin.RemovePath("grid_visualization_door"); // 门网格
// 清除旧的网格可视化 ID向后兼容
renderPlugin.RemovePath("grid_visualization_all");
renderPlugin.RemovePath("grid_visualization_channel");
LogManager.Info("[网格可视化] 网格可视化已清除");
}
else

View File

@ -699,6 +699,159 @@ namespace NavisworksTransport
}
}
/// <summary>
/// 清除网格可视化
/// </summary>
public void ClearGridVisualization()
{
try
{
lock (_lockObject)
{
// 清除所有网格可视化
RemovePath("grid_visualization_walkable");
RemovePath("grid_visualization_obstacle");
RemovePath("grid_visualization_unknown");
RemovePath("grid_visualization_door");
// 清除旧的网格可视化 ID向后兼容
RemovePath("grid_visualization_all");
RemovePath("grid_visualization_channel");
}
RequestViewRefresh();
}
catch (Exception ex)
{
LogManager.Error($"[网格可视化] 清除网格可视化失败: {ex.Message}", ex);
}
}
/// <summary>
/// 渲染网格可视化(使用专门的 GridMarker 类型)
/// </summary>
/// <param name="gridVis">网格可视化对象</param>
public void RenderGridVisualization(GridVisualization gridVis)
{
if (gridVis == null)
{
LogManager.Warning("[网格可视化] GridVisualization 对象为 null无法渲染");
return;
}
try
{
// 清除之前的网格可视化
ClearGridVisualization();
// 渲染可通行的网格点(绿色)
if (gridVis.Walkable.Count > 0)
{
RenderGridMarkers("grid_visualization_walkable", gridVis.Walkable, GridVisualizationType.Walkable);
LogManager.Info($"[网格可视化] 渲染可通行网格标记: {gridVis.Walkable.Count} 个(绿色)");
}
// 渲染障碍物网格点(灰色)
if (gridVis.Obstacle.Count > 0)
{
RenderGridMarkers("grid_visualization_obstacle", gridVis.Obstacle, GridVisualizationType.Obstacle);
LogManager.Info($"[网格可视化] 渲染障碍物网格标记: {gridVis.Obstacle.Count} 个(灰色)");
}
// 渲染未知区域网格点(红色)
if (gridVis.Unknown.Count > 0)
{
RenderGridMarkers("grid_visualization_unknown", gridVis.Unknown, GridVisualizationType.Unknown);
LogManager.Info($"[网格可视化] 渲染未知网格标记: {gridVis.Unknown.Count} 个(红色)");
}
// 渲染门网格点(半透明绿色)
if (gridVis.Door.Count > 0)
{
RenderGridMarkers("grid_visualization_door", gridVis.Door, GridVisualizationType.Door);
LogManager.Info($"[网格可视化] 渲染门网格标记: {gridVis.Door.Count} 个(半透明绿色)");
}
RequestViewRefresh();
}
catch (Exception ex)
{
LogManager.Error($"[网格可视化] 渲染失败: {ex.Message}", ex);
}
}
/// <summary>
/// 渲染一组网格标记
/// </summary>
/// <param name="pathId">路径 ID</param>
/// <param name="markers">网格标记列表</param>
/// <param name="cellType">网格可视化类型</param>
private void RenderGridMarkers(string pathId, List<GridMarker> markers, GridVisualizationType cellType)
{
if (markers == null || markers.Count == 0)
{
return;
}
var visualization = new PathVisualization
{
PathId = pathId,
PathRoute = null // 网格可视化不使用 PathRoute
};
// 创建点标记
foreach (var marker in markers)
{
var pointMarker = CreateGridMarker(marker);
visualization.PointMarkers.Add(pointMarker);
}
lock (_lockObject)
{
_pathVisualizations[pathId] = visualization;
}
}
/// <summary>
/// 创建网格标记(类型安全,无需字符串匹配)
/// </summary>
/// <param name="marker">网格标记</param>
/// <returns>圆点标记对象</returns>
private CircleMarker CreateGridMarker(GridMarker marker)
{
// 根据网格可视化类型确定颜色和透明度
RenderStyle style = new RenderStyle(Color.White, 1.0);
switch (marker.CellType)
{
case GridVisualizationType.Walkable:
style = GetRenderStyle(RenderStyleName.GridChannel);
break;
case GridVisualizationType.Obstacle:
style = GetRenderStyle(RenderStyleName.GridObstacle);
break;
case GridVisualizationType.Unknown:
style = GetRenderStyle(RenderStyleName.GridUnknown);
break;
case GridVisualizationType.Door:
// 门使用50%透明度
style = new RenderStyle(GetRenderStyle(RenderStyleName.GridChannel).Color, 0.5);
break;
}
return new CircleMarker
{
Center = marker.Position,
Normal = new Vector3D(0, 0, 1),
Radius = GetRadiusForGridVisualization(),
Color = style.Color,
Alpha = style.Alpha,
Filled = true,
PointType = PathPointType.WayPoint,
GridPointType = _gridPointType,
SequenceNumber = 0,
CreatedTime = DateTime.Now
};
}
/// <summary>
/// 只构建点标记,不构建连线
/// </summary>