将网格点可视化从球和立方体,改为圆形和正方形
This commit is contained in:
parent
9c97633411
commit
55fbcbdb48
@ -34,14 +34,14 @@ namespace NavisworksTransport
|
||||
Sphere,
|
||||
|
||||
/// <summary>
|
||||
/// 立方体
|
||||
/// 正方形
|
||||
/// </summary>
|
||||
Cube,
|
||||
Rectangle,
|
||||
|
||||
/// <summary>
|
||||
/// 点
|
||||
/// 圆
|
||||
/// </summary>
|
||||
Point
|
||||
Circle
|
||||
}
|
||||
|
||||
|
||||
@ -291,13 +291,13 @@ namespace NavisworksTransport
|
||||
private readonly object _lockObject = new object();
|
||||
private Dictionary<string, PathVisualization> _pathVisualizations = new Dictionary<string, PathVisualization>();
|
||||
private bool _isEnabled = true;
|
||||
|
||||
|
||||
// 预览点标记
|
||||
private CircleMarker _previewMarker = null;
|
||||
|
||||
|
||||
// 预览连线标记
|
||||
private List<LineMarker> _previewLines = new List<LineMarker>();
|
||||
|
||||
|
||||
// 当前网格大小(米),用于自适应点大小计算
|
||||
private double _currentGridSizeInMeters;
|
||||
|
||||
@ -305,7 +305,7 @@ namespace NavisworksTransport
|
||||
private PathVisualizationMode _visualizationMode = PathVisualizationMode.StandardLine;
|
||||
|
||||
// 网格点类型配置
|
||||
private GridPointType _gridPointType = GridPointType.Cube;
|
||||
private GridPointType _gridPointType = GridPointType.Rectangle;
|
||||
|
||||
// 车辆参数(必须通过SetVehicleParameters方法设置)
|
||||
private double _vehicleLength;
|
||||
@ -364,8 +364,8 @@ namespace NavisworksTransport
|
||||
public bool IsEnabled
|
||||
{
|
||||
get { return _isEnabled; }
|
||||
set
|
||||
{
|
||||
set
|
||||
{
|
||||
_isEnabled = value;
|
||||
// 触发视图刷新
|
||||
if (Application.ActiveDocument?.ActiveView != null)
|
||||
@ -380,8 +380,8 @@ namespace NavisworksTransport
|
||||
/// </summary>
|
||||
public int PathCount
|
||||
{
|
||||
get
|
||||
{
|
||||
get
|
||||
{
|
||||
lock (_lockObject)
|
||||
{
|
||||
return _pathVisualizations.Count;
|
||||
@ -394,8 +394,8 @@ namespace NavisworksTransport
|
||||
/// </summary>
|
||||
public int MarkerCount
|
||||
{
|
||||
get
|
||||
{
|
||||
get
|
||||
{
|
||||
lock (_lockObject)
|
||||
{
|
||||
return _pathVisualizations.Values.Sum(v => v.PointMarkers.Count);
|
||||
@ -409,7 +409,7 @@ namespace NavisworksTransport
|
||||
/// <param name="view">当前视图</param>
|
||||
/// <param name="graphics">图形上下文</param>
|
||||
public override void Render(View view, Graphics graphics)
|
||||
{
|
||||
{
|
||||
if (!_isEnabled) return;
|
||||
|
||||
try
|
||||
@ -420,7 +420,7 @@ namespace NavisworksTransport
|
||||
{
|
||||
return; // 静默返回,避免日志泛滥
|
||||
}
|
||||
|
||||
|
||||
// 检查是否有路径或预览点需要渲染
|
||||
int pathCount;
|
||||
bool hasPreviewPoint;
|
||||
@ -429,9 +429,9 @@ namespace NavisworksTransport
|
||||
pathCount = _pathVisualizations.Count;
|
||||
hasPreviewPoint = _previewMarker != null;
|
||||
}
|
||||
|
||||
|
||||
if (pathCount == 0 && !hasPreviewPoint) return;
|
||||
|
||||
|
||||
// 使用BeginModelContext确保正确的渲染上下文
|
||||
graphics.BeginModelContext();
|
||||
|
||||
@ -461,14 +461,14 @@ namespace NavisworksTransport
|
||||
RenderVehicleSpace(graphics, vehicleSpaceMarker);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// 渲染预览点(灰色)
|
||||
if (_previewMarker != null && _previewMarker.IsVisible)
|
||||
{
|
||||
graphics.Color(_previewMarker.Color, 0.7); // 使用半透明效果
|
||||
RenderPointMarker(graphics, _previewMarker);
|
||||
}
|
||||
|
||||
|
||||
// 渲染预览连线(灰色)
|
||||
if (_previewLines.Count > 0)
|
||||
{
|
||||
@ -479,7 +479,7 @@ namespace NavisworksTransport
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
graphics.EndModelContext();
|
||||
}
|
||||
catch (Exception ex)
|
||||
@ -544,7 +544,7 @@ namespace NavisworksTransport
|
||||
pathRoute.Id == "grid_visualization_door" ||
|
||||
pathRoute.Id == "grid_visualization_unknown" ||
|
||||
pathRoute.Id == "grid_visualization_obstacle";
|
||||
|
||||
|
||||
var visualization = new PathVisualization
|
||||
{
|
||||
PathId = pathRoute.Id,
|
||||
@ -558,7 +558,7 @@ namespace NavisworksTransport
|
||||
{
|
||||
_pathVisualizations[pathRoute.Id] = visualization;
|
||||
}
|
||||
|
||||
|
||||
RequestViewRefresh();
|
||||
}
|
||||
catch (Exception ex)
|
||||
@ -724,7 +724,7 @@ namespace NavisworksTransport
|
||||
|
||||
var excludedSet = new HashSet<string>(excludedPathIds.Where(id => !string.IsNullOrEmpty(id)));
|
||||
var toRemove = _pathVisualizations.Keys.Where(id => !excludedSet.Contains(id)).ToList();
|
||||
|
||||
|
||||
// 检查排除的路径是否实际存在
|
||||
var existingExcluded = excludedSet.Where(id => _pathVisualizations.ContainsKey(id)).ToList();
|
||||
var nonExistingExcluded = excludedSet.Where(id => !_pathVisualizations.ContainsKey(id)).ToList();
|
||||
@ -737,7 +737,7 @@ namespace NavisworksTransport
|
||||
removedCount++;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
if (removedCount > 0)
|
||||
{
|
||||
RequestViewRefresh();
|
||||
@ -909,7 +909,7 @@ namespace NavisworksTransport
|
||||
gridStyle = new RenderStyle(gridStyle.Color, 0.5);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
return new CircleMarker
|
||||
{
|
||||
Center = point.Position,
|
||||
@ -1230,7 +1230,7 @@ namespace NavisworksTransport
|
||||
IsVisible = true,
|
||||
PathPoint = previewPoint
|
||||
};
|
||||
|
||||
|
||||
// 请求刷新视图
|
||||
RequestViewRefresh();
|
||||
}
|
||||
@ -1254,7 +1254,7 @@ namespace NavisworksTransport
|
||||
{
|
||||
_previewMarker = null;
|
||||
_previewLines.Clear();
|
||||
|
||||
|
||||
// 请求刷新视图
|
||||
RequestViewRefresh();
|
||||
}
|
||||
@ -1284,14 +1284,14 @@ namespace NavisworksTransport
|
||||
{
|
||||
// 清除旧的预览连线
|
||||
_previewLines.Clear();
|
||||
|
||||
|
||||
// 找到预览点应该插入的最近线段
|
||||
var nearestSegment = FindNearestLineSegment(previewPoint.Position, pathPoints);
|
||||
|
||||
|
||||
if (nearestSegment.HasValue)
|
||||
{
|
||||
var (prevPoint, nextPoint) = nearestSegment.Value;
|
||||
|
||||
|
||||
// 创建两条预览连线
|
||||
// 1. 前一个点 -> 预览点
|
||||
var line1 = new LineMarker
|
||||
@ -1302,7 +1302,7 @@ namespace NavisworksTransport
|
||||
Radius = GetLineRadius() // 使用与正常连线相同的直径
|
||||
};
|
||||
_previewLines.Add(line1);
|
||||
|
||||
|
||||
// 2. 预览点 -> 后一个点
|
||||
var line2 = new LineMarker
|
||||
{
|
||||
@ -1312,13 +1312,13 @@ namespace NavisworksTransport
|
||||
Radius = GetLineRadius()
|
||||
};
|
||||
_previewLines.Add(line2);
|
||||
|
||||
|
||||
}
|
||||
else
|
||||
{
|
||||
LogManager.Warning("[预览连线渲染] 未找到合适的线段插入预览点");
|
||||
}
|
||||
|
||||
|
||||
// 请求刷新视图
|
||||
RequestViewRefresh();
|
||||
}
|
||||
@ -1341,7 +1341,7 @@ namespace NavisworksTransport
|
||||
if (_previewLines.Count > 0)
|
||||
{
|
||||
_previewLines.Clear();
|
||||
|
||||
|
||||
// 请求刷新视图
|
||||
RequestViewRefresh();
|
||||
}
|
||||
@ -1375,7 +1375,7 @@ namespace NavisworksTransport
|
||||
// 找到预览点及其索引
|
||||
var previewPointIndex = -1;
|
||||
PathPoint previewPoint = null;
|
||||
|
||||
|
||||
for (int i = 0; i < previewRoute.Points.Count; i++)
|
||||
{
|
||||
if (previewRoute.Points[i].Name.Contains("_预览"))
|
||||
@ -1385,12 +1385,12 @@ namespace NavisworksTransport
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
if (previewPoint != null && previewPointIndex >= 0)
|
||||
{
|
||||
// 只渲染预览点
|
||||
RenderPreviewPoint(previewPoint);
|
||||
|
||||
|
||||
// 只渲染与预览点相关的连线
|
||||
// 连接前一个点到预览点
|
||||
if (previewPointIndex > 0)
|
||||
@ -1405,7 +1405,7 @@ namespace NavisworksTransport
|
||||
};
|
||||
_previewLines.Add(line1);
|
||||
}
|
||||
|
||||
|
||||
// 连接预览点到下一个点
|
||||
if (previewPointIndex < previewRoute.Points.Count - 1)
|
||||
{
|
||||
@ -1418,7 +1418,7 @@ namespace NavisworksTransport
|
||||
Radius = GetLineRadius()
|
||||
};
|
||||
_previewLines.Add(line2);
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
@ -1469,7 +1469,7 @@ namespace NavisworksTransport
|
||||
{
|
||||
// 起点尺寸为网格大小的100%,并限制在合理范围内
|
||||
double standardRadius = _currentGridSizeInMeters * 1.0;
|
||||
|
||||
|
||||
// 边界限制:最小0.1米,最大0.5米
|
||||
return Math.Max(0.1, Math.Min(0.5, standardRadius));
|
||||
}
|
||||
@ -1607,13 +1607,13 @@ namespace NavisworksTransport
|
||||
{
|
||||
switch (pointMarker.GridPointType)
|
||||
{
|
||||
case GridPointType.Cube:
|
||||
case GridPointType.Rectangle:
|
||||
// 渲染立方体
|
||||
RenderCubeMarker(graphics, pointMarker);
|
||||
break;
|
||||
case GridPointType.Point:
|
||||
// 渲染点
|
||||
graphics.Point(pointMarker.Center);
|
||||
case GridPointType.Circle:
|
||||
// 渲染圆
|
||||
RenderCircleMarker(graphics, pointMarker);
|
||||
break;
|
||||
case GridPointType.Sphere:
|
||||
default:
|
||||
@ -1630,23 +1630,40 @@ namespace NavisworksTransport
|
||||
/// <param name="pointMarker">点标记</param>
|
||||
private void RenderCubeMarker(Graphics graphics, CircleMarker pointMarker)
|
||||
{
|
||||
// 计算立方体的边长(直径的一半)
|
||||
double halfSide = pointMarker.Radius;
|
||||
// 计算正方形的边长(直径)
|
||||
double sideLength = pointMarker.Radius * 2;
|
||||
|
||||
// 定义立方体的三个轴向量(沿X、Y、Z轴)
|
||||
var xVector = new Vector3D(halfSide * 2, 0, 0);
|
||||
var yVector = new Vector3D(0, halfSide * 2, 0);
|
||||
var zVector = new Vector3D(0, 0, halfSide * 2);
|
||||
// 定义正方形的两个轴向量(沿X、Y轴)
|
||||
var xVector = new Vector3D(sideLength, 0, 0);
|
||||
var yVector = new Vector3D(0, sideLength, 0);
|
||||
|
||||
// 计算立方体原点(中心点减去各轴向量的一半)
|
||||
// 计算正方形原点(中心点减去各轴向量的一半),略微抬高以避免与模型重叠
|
||||
var origin = new Point3D(
|
||||
pointMarker.Center.X - halfSide,
|
||||
pointMarker.Center.Y - halfSide,
|
||||
pointMarker.Center.Z - halfSide
|
||||
pointMarker.Center.X - pointMarker.Radius,
|
||||
pointMarker.Center.Y - pointMarker.Radius,
|
||||
pointMarker.Center.Z + 0.01
|
||||
);
|
||||
|
||||
// 使用Cuboid API渲染立方体
|
||||
graphics.Cuboid(origin, xVector, yVector, zVector, pointMarker.Filled);
|
||||
// 使用Rectangle API渲染正方形
|
||||
graphics.Rectangle(origin, xVector, yVector, pointMarker.Filled);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 渲染圆形标记
|
||||
/// </summary>
|
||||
/// <param name="graphics">图形上下文</param>
|
||||
/// <param name="pointMarker">点标记</param>
|
||||
private void RenderCircleMarker(Graphics graphics, CircleMarker pointMarker)
|
||||
{
|
||||
// 调整中心点位置,略微抬高以避免与模型重叠
|
||||
Point3D adjustCenterPoint = new Point3D(
|
||||
pointMarker.Center.X,
|
||||
pointMarker.Center.Y,
|
||||
pointMarker.Center.Z + 0.01
|
||||
);
|
||||
|
||||
// 使用Circle API渲染圆形
|
||||
graphics.Circle(adjustCenterPoint, pointMarker.Normal, pointMarker.Radius, true);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@ -1690,7 +1707,7 @@ namespace NavisworksTransport
|
||||
|
||||
// 按索引排序路径点
|
||||
var sortedPoints = pathPoints.OrderBy(p => p.Index).ToList();
|
||||
|
||||
|
||||
double minDistance = double.MaxValue;
|
||||
(PathPoint prevPoint, PathPoint nextPoint)? nearestSegment = null;
|
||||
|
||||
@ -1699,10 +1716,10 @@ namespace NavisworksTransport
|
||||
{
|
||||
var currentPoint = sortedPoints[i];
|
||||
var nextPoint = sortedPoints[i + 1];
|
||||
|
||||
|
||||
// 计算预览点到线段的距离
|
||||
var distance = CalculatePointToLineSegmentDistance(previewPosition, currentPoint.Position, nextPoint.Position);
|
||||
|
||||
|
||||
if (distance < minDistance)
|
||||
{
|
||||
minDistance = distance;
|
||||
@ -1724,36 +1741,36 @@ namespace NavisworksTransport
|
||||
{
|
||||
// 线段向量
|
||||
var lineVector = new Point3D(lineEnd.X - lineStart.X, lineEnd.Y - lineStart.Y, lineEnd.Z - lineStart.Z);
|
||||
|
||||
|
||||
// 点到线段起点的向量
|
||||
var pointVector = new Point3D(point.X - lineStart.X, point.Y - lineStart.Y, point.Z - lineStart.Z);
|
||||
|
||||
|
||||
// 计算线段长度的平方
|
||||
var lineLengthSquared = lineVector.X * lineVector.X + lineVector.Y * lineVector.Y + lineVector.Z * lineVector.Z;
|
||||
|
||||
|
||||
if (lineLengthSquared == 0)
|
||||
{
|
||||
// 线段退化为点,返回点到点的距离
|
||||
return CalculateDistance(point, lineStart);
|
||||
}
|
||||
|
||||
|
||||
// 计算投影参数t
|
||||
var t = (pointVector.X * lineVector.X + pointVector.Y * lineVector.Y + pointVector.Z * lineVector.Z) / lineLengthSquared;
|
||||
|
||||
|
||||
// 将t限制在[0,1]范围内
|
||||
t = Math.Max(0, Math.Min(1, t));
|
||||
|
||||
|
||||
// 计算线段上最近点
|
||||
var closestPoint = new Point3D(
|
||||
lineStart.X + t * lineVector.X,
|
||||
lineStart.Y + t * lineVector.Y,
|
||||
lineStart.Z + t * lineVector.Z
|
||||
);
|
||||
|
||||
|
||||
// 返回点到最近点的距离
|
||||
return CalculateDistance(point, closestPoint);
|
||||
}
|
||||
|
||||
|
||||
private static DateTime _lastRefreshTime = DateTime.MinValue;
|
||||
|
||||
#endregion
|
||||
@ -1821,10 +1838,10 @@ namespace NavisworksTransport
|
||||
/// <summary>
|
||||
/// 位置(Center的别名,用于预览点兼容性)
|
||||
/// </summary>
|
||||
public Point3D Position
|
||||
{
|
||||
get { return Center; }
|
||||
set { Center = value; }
|
||||
public Point3D Position
|
||||
{
|
||||
get { return Center; }
|
||||
set { Center = value; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@ -1837,4 +1854,4 @@ namespace NavisworksTransport
|
||||
return $"CircleMarker[序号={SequenceNumber}, 类型={PointType}, 中心=({Center.X:F2},{Center.Y:F2},{Center.Z:F2}), 半径={Radius:F2}]";
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -27,7 +27,7 @@ namespace NavisworksTransport.UI.WPF.ViewModels
|
||||
private bool _showDoorGrid = false;
|
||||
|
||||
// 网格点类型字段
|
||||
private GridPointType _gridPointType = GridPointType.Cube;
|
||||
private GridPointType _gridPointType = GridPointType.Rectangle;
|
||||
private ObservableCollection<GridPointType> _gridPointTypes;
|
||||
|
||||
// 路径可视化模式字段
|
||||
@ -121,9 +121,8 @@ namespace NavisworksTransport.UI.WPF.ViewModels
|
||||
if (SetProperty(ref _gridPointType, value))
|
||||
{
|
||||
// 通知相关的单选按钮属性更新
|
||||
OnPropertyChanged(nameof(IsCubePointType));
|
||||
OnPropertyChanged(nameof(IsSpherePointType));
|
||||
OnPropertyChanged(nameof(IsPointPointType));
|
||||
OnPropertyChanged(nameof(IsRectanglePointType));
|
||||
OnPropertyChanged(nameof(IsCirclePointType));
|
||||
OnGridPointTypeChanged();
|
||||
}
|
||||
}
|
||||
@ -132,29 +131,14 @@ namespace NavisworksTransport.UI.WPF.ViewModels
|
||||
/// <summary>
|
||||
/// 是否使用立方体点类型
|
||||
/// </summary>
|
||||
public bool IsCubePointType
|
||||
public bool IsRectanglePointType
|
||||
{
|
||||
get => _gridPointType == GridPointType.Cube;
|
||||
get => _gridPointType == GridPointType.Rectangle;
|
||||
set
|
||||
{
|
||||
if (value)
|
||||
{
|
||||
GridPointType = GridPointType.Cube;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 是否使用球形点类型
|
||||
/// </summary>
|
||||
public bool IsSpherePointType
|
||||
{
|
||||
get => _gridPointType == GridPointType.Sphere;
|
||||
set
|
||||
{
|
||||
if (value)
|
||||
{
|
||||
GridPointType = GridPointType.Sphere;
|
||||
GridPointType = GridPointType.Rectangle;
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -162,14 +146,14 @@ namespace NavisworksTransport.UI.WPF.ViewModels
|
||||
/// <summary>
|
||||
/// 是否使用点状点类型
|
||||
/// </summary>
|
||||
public bool IsPointPointType
|
||||
public bool IsCirclePointType
|
||||
{
|
||||
get => _gridPointType == GridPointType.Point;
|
||||
get => _gridPointType == GridPointType.Circle;
|
||||
set
|
||||
{
|
||||
if (value)
|
||||
{
|
||||
GridPointType = GridPointType.Point;
|
||||
GridPointType = GridPointType.Circle;
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -547,7 +531,7 @@ namespace NavisworksTransport.UI.WPF.ViewModels
|
||||
SelectedLogLevel = currentLevel.ToString();
|
||||
|
||||
// 设置默认网格点类型
|
||||
GridPointType = GridPointType.Cube;
|
||||
GridPointType = GridPointType.Rectangle;
|
||||
|
||||
// 初始化系统信息
|
||||
PluginVersion = "v1.0";
|
||||
|
||||
@ -173,23 +173,17 @@ NavisworksTransport 系统管理页签视图 - 采用与其他页签一致的Nav
|
||||
Orientation="Horizontal"
|
||||
VerticalAlignment="Center"
|
||||
Margin="5,0,0,0">
|
||||
<RadioButton Content="立方体"
|
||||
<RadioButton Content="正方形"
|
||||
GroupName="GridPointType"
|
||||
IsChecked="{Binding IsCubePointType}"
|
||||
IsChecked="{Binding IsRectanglePointType}"
|
||||
Margin="0,0,20,0"
|
||||
VerticalAlignment="Center"
|
||||
ToolTip="显示立方体网格点"/>
|
||||
<RadioButton Content="球形"
|
||||
<RadioButton Content="圆"
|
||||
GroupName="GridPointType"
|
||||
IsChecked="{Binding IsSpherePointType}"
|
||||
Margin="0,0,20,0"
|
||||
IsChecked="{Binding IsCirclePointType}"
|
||||
VerticalAlignment="Center"
|
||||
ToolTip="显示球形网格点"/>
|
||||
<RadioButton Content="点"
|
||||
GroupName="GridPointType"
|
||||
IsChecked="{Binding IsPointPointType}"
|
||||
VerticalAlignment="Center"
|
||||
ToolTip="显示点状网格点"/>
|
||||
ToolTip="显示圆形网格点"/>
|
||||
</StackPanel>
|
||||
</Grid>
|
||||
</StackPanel>
|
||||
|
||||
Loading…
Reference in New Issue
Block a user