增加带状连线风格

This commit is contained in:
tian 2026-01-04 11:59:50 +08:00
parent 0081015d0b
commit ec3ef5b30e
3 changed files with 256 additions and 45 deletions

View File

@ -17,6 +17,11 @@ namespace NavisworksTransport
/// </summary>
StandardLine,
/// <summary>
/// 带状连线模式 - 长方体连线
/// </summary>
RibbonLine,
/// <summary>
/// 车辆通行空间模式 - 矩形通道
/// </summary>
@ -239,6 +244,11 @@ namespace NavisworksTransport
/// </summary>
public List<Point3D> SampledPoints { get; set; }
/// <summary>
/// 带状连线高度(仅用于 RibbonLine 模式)
/// </summary>
public double Height { get; set; }
public override string ToString()
{
return $"LineMarker[{FromIndex}->{ToIndex}, 类型={SegmentType}, 起点=({StartPoint.X:F2},{StartPoint.Y:F2},{StartPoint.Z:F2}), 终点=({EndPoint.X:F2},{EndPoint.Y:F2},{EndPoint.Z:F2})]";
@ -717,6 +727,18 @@ namespace NavisworksTransport
}
}
/// <summary>
/// 获取所有路径可视化对象
/// </summary>
/// <returns>所有路径可视化对象的列表</returns>
public List<PathVisualization> GetAllPathVisualizations()
{
lock (_lockObject)
{
return _pathVisualizations.Values.ToList();
}
}
/// <summary>
/// 判断是否为网格可视化路径
/// </summary>
@ -981,6 +1003,9 @@ namespace NavisworksTransport
}
}
// 计算带状连线的高度比切点标记低GetLineRadius() * 0.2
double ribbonHeight = GetLineRadius() * 0.2;
// 3. 构建路径连线Edges包含直线段和圆弧段
foreach (var edge in edges)
{
@ -996,7 +1021,8 @@ namespace NavisworksTransport
Color = GetRenderStyle(RenderStyleName.Line).Color,
Radius = GetLineRadius(),
SegmentType = PathSegmentType.Straight,
SampledPoints = edge.SampledPoints
SampledPoints = edge.SampledPoints,
Height = ribbonHeight // 设置带状连线高度
};
visualization.PathLineMarkers.Add(lineMarker);
}
@ -1012,7 +1038,8 @@ namespace NavisworksTransport
Radius = GetLineRadius(),
SegmentType = PathSegmentType.Arc,
Trajectory = edge.Trajectory,
SampledPoints = edge.SampledPoints
SampledPoints = edge.SampledPoints,
Height = ribbonHeight // 设置带状连线高度
};
visualization.PathLineMarkers.Add(arcMarker);
@ -1749,22 +1776,27 @@ namespace NavisworksTransport
}
/// <summary>
/// 渲染车辆通行空间(矩形通道)- 使用Cuboid API简化实现
/// 渲染长方体标记(通用方法)
/// </summary>
/// <param name="graphics">图形上下文</param>
/// <param name="vehicleSpace">车辆通行空间标记</param>
private void RenderVehicleSpace(Graphics graphics, VehicleSpaceMarker vehicleSpace)
/// <param name="startPoint">起点</param>
/// <param name="endPoint">终点</param>
/// <param name="width">宽度</param>
/// <param name="height">高度</param>
/// <param name="color">颜色</param>
/// <param name="alpha">透明度</param>
private void RenderCuboidMarker(Graphics graphics, Point3D startPoint, Point3D endPoint, double width, double height, Color color, double alpha)
{
try
{
// 计算通道方向向量
// 计算方向向量
var direction = new Vector3D(
vehicleSpace.EndPoint.X - vehicleSpace.StartPoint.X,
vehicleSpace.EndPoint.Y - vehicleSpace.StartPoint.Y,
vehicleSpace.EndPoint.Z - vehicleSpace.StartPoint.Z
endPoint.X - startPoint.X,
endPoint.Y - startPoint.Y,
endPoint.Z - startPoint.Z
);
// 计算通道长度
// 计算长度
var length = Math.Sqrt(direction.X * direction.X + direction.Y * direction.Y + direction.Z * direction.Z);
if (length < 0.001) // 避免零长度线段
@ -1789,33 +1821,72 @@ namespace NavisworksTransport
right = new Vector3D(right.X / rightLength, right.Y / rightLength, right.Z / rightLength);
}
// 计算通道的边界框和向量
var halfWidth = vehicleSpace.Width / 2.0;
// 计算长方体的边界框和向量
var halfWidth = width / 2.0;
// 计算立方体原点(起点左下角)
var origin = new Point3D(
vehicleSpace.StartPoint.X - halfWidth * right.X,
vehicleSpace.StartPoint.Y - halfWidth * right.Y,
vehicleSpace.StartPoint.Z
startPoint.X - halfWidth * right.X,
startPoint.Y - halfWidth * right.Y,
startPoint.Z
);
// 定义立方体的三个轴向量
var xVector = new Vector3D(direction.X * length, direction.Y * length, direction.Z * length); // 长度方向
var yVector = new Vector3D(right.X * vehicleSpace.Width, right.Y * vehicleSpace.Width, right.Z * vehicleSpace.Width); // 宽度方向
var zVector = new Vector3D(0, 0, vehicleSpace.Height); // 高度方向
var yVector = new Vector3D(right.X * width, right.Y * width, right.Z * width); // 宽度方向
var zVector = new Vector3D(0, 0, height); // 高度方向
// 设置颜色和透明度
graphics.Color(vehicleSpace.Color, vehicleSpace.Alpha);
graphics.Color(color, alpha);
// 使用Cuboid API渲染长方体通道
// 使用Cuboid API渲染长方体
graphics.Cuboid(origin, xVector, yVector, zVector, true);
}
catch (Exception ex)
{
LogManager.Error($"[车辆空间渲染] 渲染车辆通行空间失败: {ex.Message}", ex);
LogManager.Error($"[长方体渲染] 渲染长方体失败: {ex.Message}", ex);
}
}
/// <summary>
/// 渲染车辆通行空间(矩形通道)- 使用Cuboid API简化实现
/// </summary>
/// <param name="graphics">图形上下文</param>
/// <param name="vehicleSpace">车辆通行空间标记</param>
private void RenderVehicleSpace(Graphics graphics, VehicleSpaceMarker vehicleSpace)
{
var style = GetRenderStyle(RenderStyleName.VehicleSpace);
RenderCuboidMarker(
graphics,
vehicleSpace.StartPoint,
vehicleSpace.EndPoint,
vehicleSpace.Width,
vehicleSpace.Height,
vehicleSpace.Color,
vehicleSpace.Alpha
);
}
/// <summary>
/// 渲染带状连线(长方体)
/// </summary>
/// <param name="graphics">图形上下文</param>
/// <param name="lineMarker">连线标记</param>
private void RenderRibbonLineMarker(Graphics graphics, LineMarker lineMarker)
{
// 计算带状连线的宽度(直径)
var width = lineMarker.Radius * 2;
RenderCuboidMarker(
graphics,
lineMarker.StartPoint,
lineMarker.EndPoint,
width,
lineMarker.Height,
lineMarker.Color,
1.0 // 带状连线使用不透明
);
}
/// <summary>
/// 渲染点标记
@ -1922,20 +1993,51 @@ namespace NavisworksTransport
/// <param name="lineMarker">连线标记</param>
private void RenderLineMarker(Graphics graphics, LineMarker lineMarker)
{
if (lineMarker.SegmentType == PathSegmentType.Arc &&
lineMarker.SampledPoints != null &&
lineMarker.SampledPoints.Count >= 2)
if (_visualizationMode == PathVisualizationMode.RibbonLine)
{
// 圆弧段:多段圆柱体
for (int i = 0; i < lineMarker.SampledPoints.Count - 1; i++)
// 带状连线模式:使用长方体渲染
if (lineMarker.SegmentType == PathSegmentType.Arc &&
lineMarker.SampledPoints != null &&
lineMarker.SampledPoints.Count >= 2)
{
graphics.Cylinder(lineMarker.SampledPoints[i], lineMarker.SampledPoints[i + 1], lineMarker.Radius);
// 圆弧段:多段长方体拼接
for (int i = 0; i < lineMarker.SampledPoints.Count - 1; i++)
{
var segmentMarker = new LineMarker
{
StartPoint = lineMarker.SampledPoints[i],
EndPoint = lineMarker.SampledPoints[i + 1],
Radius = lineMarker.Radius,
Height = lineMarker.Height,
Color = lineMarker.Color
};
RenderRibbonLineMarker(graphics, segmentMarker);
}
}
else
{
// 直线段:单个长方体
RenderRibbonLineMarker(graphics, lineMarker);
}
}
else
{
// 直线段:单个圆柱体
graphics.Cylinder(lineMarker.StartPoint, lineMarker.EndPoint, lineMarker.Radius);
// 标准连线模式:使用圆柱体渲染
if (lineMarker.SegmentType == PathSegmentType.Arc &&
lineMarker.SampledPoints != null &&
lineMarker.SampledPoints.Count >= 2)
{
// 圆弧段:多段圆柱体
for (int i = 0; i < lineMarker.SampledPoints.Count - 1; i++)
{
graphics.Cylinder(lineMarker.SampledPoints[i], lineMarker.SampledPoints[i + 1], lineMarker.Radius);
}
}
else
{
// 直线段:单个圆柱体
graphics.Cylinder(lineMarker.StartPoint, lineMarker.EndPoint, lineMarker.Radius);
}
}
}

View File

@ -9,6 +9,7 @@ using System.Linq;
using System.IO;
using Microsoft.Win32;
using Autodesk.Navisworks.Api;
using NavisApplication = Autodesk.Navisworks.Api.Application;
using NavisworksTransport.Core;
using NavisworksTransport.Core.Config;
using NavisworksTransport.Commands;
@ -81,7 +82,9 @@ namespace NavisworksTransport.UI.WPF.ViewModels
private bool _showDoorGrid = false;
private GridPointType _gridPointType = GridPointType.Rectangle;
private bool _isStandardLineMode = true;
private bool _isRibbonLineMode = false;
private bool _isVehicleSpaceMode = false;
private bool _showControlVisualization = true; // 默认显示控制点
// 路径策略参数
private PathStrategyOption _selectedPathStrategy;
@ -491,6 +494,7 @@ namespace NavisworksTransport.UI.WPF.ViewModels
{
if (value)
{
IsRibbonLineMode = false;
IsVehicleSpaceMode = false;
OnPathVisualizationModeChanged();
}
@ -511,12 +515,48 @@ namespace NavisworksTransport.UI.WPF.ViewModels
if (value)
{
IsStandardLineMode = false;
IsRibbonLineMode = false;
OnPathVisualizationModeChanged();
}
}
}
}
/// <summary>
/// 是否使用带状连线模式
/// </summary>
public bool IsRibbonLineMode
{
get => _isRibbonLineMode;
set
{
if (SetProperty(ref _isRibbonLineMode, value))
{
if (value)
{
IsStandardLineMode = false;
IsVehicleSpaceMode = false;
OnPathVisualizationModeChanged();
}
}
}
}
/// <summary>
/// 是否显示控制点可视化(用户意图)
/// </summary>
public bool ShowControlVisualization
{
get => _showControlVisualization;
set
{
if (SetProperty(ref _showControlVisualization, value))
{
OnControlVisualizationChanged();
}
}
}
#endregion
/// <summary>
@ -2364,10 +2404,27 @@ namespace NavisworksTransport.UI.WPF.ViewModels
var renderPlugin = PathPointRenderPlugin.Instance;
if (renderPlugin != null)
{
var mode = IsVehicleSpaceMode ? PathVisualizationMode.VehicleSpace : PathVisualizationMode.StandardLine;
renderPlugin.VisualizationMode = mode;
PathVisualizationMode mode;
string modeName;
LogManager.Info($"路径可视化模式已更改: {(IsVehicleSpaceMode ? "" : "线")}");
if (IsVehicleSpaceMode)
{
mode = PathVisualizationMode.VehicleSpace;
modeName = "车辆通行空间";
}
else if (IsRibbonLineMode)
{
mode = PathVisualizationMode.RibbonLine;
modeName = "带状连线";
}
else
{
mode = PathVisualizationMode.StandardLine;
modeName = "柱形连线";
}
renderPlugin.VisualizationMode = mode;
LogManager.Info($"路径可视化模式已更改: {modeName}");
UpdateMainStatus("路径可视化模式已更新");
}
else
@ -2382,6 +2439,47 @@ namespace NavisworksTransport.UI.WPF.ViewModels
}
}
/// <summary>
/// 控制点可视化变更事件处理
/// </summary>
private void OnControlVisualizationChanged()
{
try
{
var renderPlugin = PathPointRenderPlugin.Instance;
if (renderPlugin != null)
{
// 更新所有路径的 ShowControlVisualization 属性
lock (typeof(PathPointRenderPlugin))
{
var allVisualizations = renderPlugin.GetAllPathVisualizations();
foreach (var visualization in allVisualizations)
{
visualization.ShowControlVisualization = ShowControlVisualization;
}
}
// 触发视图刷新
if (NavisApplication.ActiveDocument?.ActiveView != null)
{
NavisApplication.ActiveDocument.ActiveView.RequestDelayedRedraw(ViewRedrawRequests.Render);
}
LogManager.Info($"控制点可视化已更改: {(ShowControlVisualization ? "" : "")}");
UpdateMainStatus("控制点可视化已更新");
}
else
{
LogManager.Warning("无法获取PathPointRenderPlugin实例");
}
}
catch (Exception ex)
{
LogManager.Error($"应用控制点可视化设置失败: {ex.Message}", ex);
UpdateMainStatus("控制点可视化设置失败");
}
}
/// <summary>
/// 清理自动路径相关的事件订阅
/// </summary>

View File

@ -445,22 +445,33 @@ NavisworksTransport 路径编辑页签视图 - 采用与动画控制和分层管
VerticalAlignment="Center"/>
<StackPanel Grid.Column="1"
Orientation="Vertical"
Orientation="Horizontal"
VerticalAlignment="Center"
Margin="5,0,0,0">
<!-- 可视化模式选择 -->
<StackPanel Orientation="Horizontal" Margin="0,0,0,5">
<RadioButton Content="标准连线"
GroupName="PathVisualizationMode"
IsChecked="{Binding IsStandardLineMode}"
Margin="0,0,20,0"
VerticalAlignment="Center"
ToolTip="显示标准圆柱形连线"/>
<RadioButton Content="通行空间"
GroupName="PathVisualizationMode"
IsChecked="{Binding IsVehicleSpaceMode}"
VerticalAlignment="Center"
ToolTip="显示通行空间(矩形通道)"/>
</StackPanel>
<RadioButton Content="柱形连线"
GroupName="PathVisualizationMode"
IsChecked="{Binding IsStandardLineMode}"
Margin="0,0,20,0"
VerticalAlignment="Center"
ToolTip="显示柱形连线(圆柱体)"/>
<RadioButton Content="带状连线"
GroupName="PathVisualizationMode"
IsChecked="{Binding IsRibbonLineMode}"
Margin="0,0,20,0"
VerticalAlignment="Center"
ToolTip="显示带状连线(长方体)"/>
<RadioButton Content="通行空间"
GroupName="PathVisualizationMode"
IsChecked="{Binding IsVehicleSpaceMode}"
Margin="0,0,20,0"
VerticalAlignment="Center"
ToolTip="显示通行空间(矩形通道)"/>
<!-- 显示控制点开关 -->
<CheckBox Content="显示控制点"
IsChecked="{Binding ShowControlVisualization}"
VerticalAlignment="Center"
ToolTip="显示控制点可视化(用户意图)"/>
</StackPanel>
</Grid>