From ec3ef5b30e527628090e7967b8bd1f8b9ebcd7b0 Mon Sep 17 00:00:00 2001
From: tian <11429339@qq.com>
Date: Sun, 4 Jan 2026 11:59:50 +0800
Subject: [PATCH] =?UTF-8?q?=E5=A2=9E=E5=8A=A0=E5=B8=A6=E7=8A=B6=E8=BF=9E?=
=?UTF-8?q?=E7=BA=BF=E9=A3=8E=E6=A0=BC?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
src/Core/PathPointRenderPlugin.cs | 158 ++++++++++++++----
src/UI/WPF/ViewModels/PathEditingViewModel.cs | 104 +++++++++++-
src/UI/WPF/Views/PathEditingView.xaml | 39 +++--
3 files changed, 256 insertions(+), 45 deletions(-)
diff --git a/src/Core/PathPointRenderPlugin.cs b/src/Core/PathPointRenderPlugin.cs
index bd1e8e1..cebae8c 100644
--- a/src/Core/PathPointRenderPlugin.cs
+++ b/src/Core/PathPointRenderPlugin.cs
@@ -17,6 +17,11 @@ namespace NavisworksTransport
///
StandardLine,
+ ///
+ /// 带状连线模式 - 长方体连线
+ ///
+ RibbonLine,
+
///
/// 车辆通行空间模式 - 矩形通道
///
@@ -239,6 +244,11 @@ namespace NavisworksTransport
///
public List SampledPoints { get; set; }
+ ///
+ /// 带状连线高度(仅用于 RibbonLine 模式)
+ ///
+ 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
}
}
+ ///
+ /// 获取所有路径可视化对象
+ ///
+ /// 所有路径可视化对象的列表
+ public List GetAllPathVisualizations()
+ {
+ lock (_lockObject)
+ {
+ return _pathVisualizations.Values.ToList();
+ }
+ }
+
///
/// 判断是否为网格可视化路径
///
@@ -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
}
///
- /// 渲染车辆通行空间(矩形通道)- 使用Cuboid API简化实现
+ /// 渲染长方体标记(通用方法)
///
/// 图形上下文
- /// 车辆通行空间标记
- private void RenderVehicleSpace(Graphics graphics, VehicleSpaceMarker vehicleSpace)
+ /// 起点
+ /// 终点
+ /// 宽度
+ /// 高度
+ /// 颜色
+ /// 透明度
+ 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);
}
}
+ ///
+ /// 渲染车辆通行空间(矩形通道)- 使用Cuboid API简化实现
+ ///
+ /// 图形上下文
+ /// 车辆通行空间标记
+ 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
+ );
+ }
+
+ ///
+ /// 渲染带状连线(长方体)
+ ///
+ /// 图形上下文
+ /// 连线标记
+ 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 // 带状连线使用不透明
+ );
+ }
+
///
/// 渲染点标记
@@ -1922,20 +1993,51 @@ namespace NavisworksTransport
/// 连线标记
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);
+ }
}
}
diff --git a/src/UI/WPF/ViewModels/PathEditingViewModel.cs b/src/UI/WPF/ViewModels/PathEditingViewModel.cs
index 91064e1..2c627c3 100644
--- a/src/UI/WPF/ViewModels/PathEditingViewModel.cs
+++ b/src/UI/WPF/ViewModels/PathEditingViewModel.cs
@@ -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();
}
}
}
}
+ ///
+ /// 是否使用带状连线模式
+ ///
+ public bool IsRibbonLineMode
+ {
+ get => _isRibbonLineMode;
+ set
+ {
+ if (SetProperty(ref _isRibbonLineMode, value))
+ {
+ if (value)
+ {
+ IsStandardLineMode = false;
+ IsVehicleSpaceMode = false;
+ OnPathVisualizationModeChanged();
+ }
+ }
+ }
+ }
+
+ ///
+ /// 是否显示控制点可视化(用户意图)
+ ///
+ public bool ShowControlVisualization
+ {
+ get => _showControlVisualization;
+ set
+ {
+ if (SetProperty(ref _showControlVisualization, value))
+ {
+ OnControlVisualizationChanged();
+ }
+ }
+ }
+
#endregion
///
@@ -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
}
}
+ ///
+ /// 控制点可视化变更事件处理
+ ///
+ 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("控制点可视化设置失败");
+ }
+ }
+
///
/// 清理自动路径相关的事件订阅
///
diff --git a/src/UI/WPF/Views/PathEditingView.xaml b/src/UI/WPF/Views/PathEditingView.xaml
index c494c22..9f78557 100644
--- a/src/UI/WPF/Views/PathEditingView.xaml
+++ b/src/UI/WPF/Views/PathEditingView.xaml
@@ -445,22 +445,33 @@ NavisworksTransport 路径编辑页签视图 - 采用与动画控制和分层管
VerticalAlignment="Center"/>
-
-
-
-
+
+
+
+
+