fix:网格线增加

master
sunhonglei 5 months ago
parent 652c8604a6
commit ea83fee61b
  1. 10
      Views/UserControl/Viewport3D.xaml
  2. 28
      Views/UserControl/Viewport3D.xaml.cs
  3. 99
      Views/UserControl/ViewportData/Helper/LineCalculationHelper.cs
  4. 74
      Views/UserControl/ViewportData/Helper/ViewportHelperPro.cs
  5. 34
      Views/UserControl/ViewportData/Helper/ViewportManager.cs

@ -67,13 +67,15 @@
<!-- <MenuItem Header="{StaticResource ViewportRightMenuSelectFaceLengthText}" x:Name="ViewportRightMenuSelectFaceLengthText" IsCheckable="True" StaysOpenOnClick="True" Checked="MenuItem_OnCheckedChanged" Unchecked="MenuItem_OnCheckedChanged"/> -->
<!-- <MenuItem Header="{StaticResource ViewportRightMenuSelectFaceAngleText}" x:Name="ViewportRightMenuSelectFaceAngleText" IsCheckable="True" StaysOpenOnClick="True" Checked="MenuItem_OnCheckedChanged" Unchecked="MenuItem_OnCheckedChanged"/> -->
<MenuItem Header="{StaticResource ViewportRightMenuSelectFaceKind}" x:Name="ViewportRightMenuSelectFaceKind" IsCheckable="True" StaysOpenOnClick="True" Checked="MenuItem_OnCheckedChanged" Unchecked="MenuItem_OnCheckedChanged"/>
<MenuItem Header="{StaticResource ViewportRightMenuShowMeshLines}" x:Name="ViewportRightMenuShowMeshLines" IsCheckable="True" StaysOpenOnClick="True" Checked="MenuItem_OnCheckedChanged" Unchecked="MenuItem_OnCheckedChanged"/>
</ContextMenu>
</Border.ContextMenu>
<hx:Viewport3DX x:Name="Viewport3Dx" ShowCoordinateSystem="True"
PreviewMouseRightButtonUp="UIElement_OnPreviewMouseRightButtonUp"
PreviewMouseRightButtonDown="UIElement_OnPreviewMouseRightButtonDown"
PreviewMouseMove="Viewport3Dx_OnPreviewMouseMove"
MouseLeftButtonDown="Viewport3Dx_OnMouseLeftButtonDown">
MouseLeftButtonDown="Viewport3Dx_MouseLeftButtonDown"
MouseDoubleClick="Viewport3Dx_OnMouseLeftButtonDown">
<hx:Viewport3DX.EffectsManager><hx:EffectsManager ></hx:EffectsManager></hx:Viewport3DX.EffectsManager>
<hx:Viewport3DX.InputBindings>
<KeyBinding Key="B" Command="hx:ViewportCommands.BackView" />
@ -85,8 +87,12 @@
<KeyBinding Command="hx:ViewportCommands.ZoomExtents" Gesture="Control+E" />
<MouseBinding Command="hx:ViewportCommands.Rotate" Gesture="RightClick" />
<MouseBinding Command="hx:ViewportCommands.Zoom" Gesture="MiddleClick" />
<MouseBinding Command="hx:ViewportCommands.Pan" Gesture="LeftClick" />
<!--<MouseBinding Command="hx:ViewportCommands.Pan" Gesture="LeftClick" />-->
</hx:Viewport3DX.InputBindings>
<hx:AxisPlaneGridModel3D
AutoSpacing="true"
RenderShadowMap="False"
Offset="0" />
</hx:Viewport3DX>
</Border>
<Grid Grid.Row="2" Height="100">

@ -15,6 +15,7 @@ using HelixToolkit.Wpf.SharpDX;
using SharpDX;
using SharpDX.Direct3D11;
using SharpDX.DXGI;
using MathNet.Numerics;
namespace SparkClient.Views.UserControl;
@ -60,6 +61,10 @@ public partial class Viewport3D
var a = Viewport3Dx.Items;
#if DEBUG
Viewport3Dx.ShowViewCube = true;
Viewport3Dx.ShowCoordinateSystem = true;
#endif
}
@ -405,6 +410,17 @@ public partial class Viewport3D
//双击选择面的选择同类面
ViewportManager.DoubleClickSelectShowPlaneType = checkResult;
ViewportManager.ResetChooseAddModels();
break;
case "ViewportRightMenuShowMeshLines":
var maxDimension = ViewportManager.ModelBounds.Size.Length();
var distance = maxDimension * 1.2; // 调整相机到模型的距离,保证视野范围内
var center = ViewportManager.ModelBounds.Center;
var camera = Viewport3Dx.Camera as HelixToolkit.Wpf.SharpDX.PerspectiveCamera;
camera.Position = new Point3D(center.X, center.Y - distance, center.Z); // 从底部看,Y轴负方向
camera.UpDirection = new Vector3D(0, 0, -1);
ViewportManager.ShowMeshLines(checkResult);
//camera.LookDirection = new Vector3D(center.X - camera.Position.X, center.Y - camera.Position.Y, center.Z - camera.Position.Z);
break;
}
}
@ -578,4 +594,16 @@ public partial class Viewport3D
//Viewport3Dx.ShowFrameRate = !Viewport3Dx.ShowFrameRate;
//Viewport3Dx.ShowTriangleCountInfo = !Viewport3Dx.ShowTriangleCountInfo;
}
private void Viewport3Dx_MouseLeftButtonDown(object sender, MouseButtonEventArgs e)
{
var mousePosition = e.GetPosition(Viewport3Dx);
var hits = Viewport3Dx.FindHits(mousePosition);
// 如果没有命中任何 3D 对象
if (hits == null || hits.Count == 0)
{
ViewportManager.ClearDicModels();
return;
}
}
}

@ -0,0 +1,99 @@
using SharpDX;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Media.Media3D;
namespace SparkClient.Views.UserControl.ViewportData.Helper
{
internal class LineCalculationHelper
{
private readonly float Y = -0.01F;
private Vector3 point1;
private Vector3 point2;
/// <summary>
/// 常数a(y=ax+b)
/// </summary>
private float a;
/// <summary>
/// 常数b(y=ax+b)
/// </summary>
private float b;
public LineCalculationHelper(Vector3 point1, Vector3 point2) {
this.point1 = point1;
this.point2 = point2;
this.a = calA(point1, point2);
this.b = calB(point1, a);
}
/// <summary>
/// 常数a的计算
/// </summary>
/// <param name="point1"></param>
/// <param name="point2"></param>
/// <returns></returns>
private float calA(Vector3 point1, Vector3 point2)
{
return (point1.Z - point2.Z) / (point1.X - point2.X);
}
/// <summary>
/// 常数b的计算
/// </summary>
/// <param name="point1"></param>
/// <param name="a"></param>
/// <returns></returns>
private float calB(Vector3 point1, float a)
{
return -(a * point1.X)+point1.Z;
}
public Tuple<Vector3, Vector3> calXline(float length)
{
var x1 = 5;
var z1 = calZ(x1);
var x2 = -5;
var z2 = calZ(x2);
return new Tuple<Vector3, Vector3>(new Vector3(x1, Y, z1), new Vector3(x2, Y, z2));
}
public Tuple<Vector3, Vector3> calYline(float length)
{
var x1 = 5;
var z1 = calZVertical(x1);
var x2 = -5;
var z2 = calZVertical(x2);
return new Tuple<Vector3, Vector3>(new Vector3(x1, Y, z1), new Vector3(x2, Y, z2));
}
public Tuple<Vector3, Vector3> calLineOfOffset(Tuple<Vector3, Vector3> tuple, float d)
{
var point1 = tuple.Item1;
var point2 = tuple.Item2;
var x1 = point1.X - d * (point2.Z - point1.Z)/
(float)Math.Sqrt(Square(point2.X - point1.X) + Square(point2.Z - point1.Z));
var z1 = point1.Z + d * (point2.X - point1.X) /
(float)Math.Sqrt(Square(point2.X - point1.X) + Square(point2.Z - point1.Z));
var x2 = point2.X - d * (point2.Z - point1.Z) /
(float)Math.Sqrt(Square(point2.X - point1.X) + Square(point2.Z - point1.Z));
var z2 = point2.Z + d * (point2.X - point1.X) /
(float)Math.Sqrt(Square(point2.X - point1.X) + Square(point2.Z - point1.Z));
return new Tuple<Vector3, Vector3>(new Vector3(x1, Y, z1), new Vector3(x2, Y, z2));
}
float Square(float number)
{
return number * number;
}
public float calZ(float x, float offset = 0)
{
return a * x + b + offset;
}
public float calZVertical(float x, float offset = 0)
{
return (-x / a) + b + offset;
}
}
}

@ -21,6 +21,8 @@ using SparkClient.Views.UserControl.ViewportData.Enum;
using SparkClient.Views.UserControl.ViewportData.Entity;
using Color = SharpDX.Color;
using GeometryModel3D = HelixToolkit.Wpf.SharpDX.GeometryModel3D;
using NPOI.SS.Formula.Functions;
using MeshGeometry3D = HelixToolkit.Wpf.SharpDX.MeshGeometry3D;
namespace SparkClient.Views.UserControl.ViewportData.Helper;
@ -1274,6 +1276,78 @@ public class ViewportHelperPro
lights.ForEach(item => viewport.Items.Remove(item));
}
public static List<LineGeometryModel3D> ShowMeshLines(List<Viewport3DTriangleEntity> entities, double thickness = 1.0)
{
List<LineGeometryModel3D> lines = new();
var Y = -0.01F;
var center = ViewportManager.CenterVector;
center.Y = Y;
Viewport3DTriangleEntity firstPoint = entities.Where(x => x.PlaneType == PlaneType.TableFacet).FirstOrDefault();
//var b = ((center.Z * firstPoint.Point1.X) - (firstPoint.Point1.Z * center.X)) / (firstPoint.Point1.X - center.X);
//var a = (firstPoint.Point1.Z - b) / firstPoint.Point1.X;
var lineCal = new LineCalculationHelper(firstPoint.Point1, center);
var edgeLines = new List<Tuple<Vector3, Vector3>>();
Color4 XlineColor =new Color4(255f, 0f, 0f, 1f);
var x1 = 5;
var z1 = lineCal.calZ(x1);
var x2 = -5;
var z2 = lineCal.calZ(x2);
edgeLines.Add(new Tuple<Vector3, Vector3>(new Vector3(x1, Y, z1), new Vector3(x2, Y, z2)));
lines.Add(DisplayLineModel3D(edgeLines, XlineColor));
edgeLines.Add(lineCal.calLineOfOffset(new Tuple<Vector3, Vector3>(new Vector3(x1, Y, z1), new Vector3(x2, Y, z2)),2));
lines.Add(DisplayLineModel3D(edgeLines, XlineColor));
edgeLines.Add(lineCal.calLineOfOffset(new Tuple<Vector3, Vector3>(new Vector3(x1, Y, z1), new Vector3(x2, Y, z2)), -2));
lines.Add(DisplayLineModel3D(edgeLines, XlineColor));
Color4 YlineColor = new Color4(0F, 255f, 0f, 1f);
var x3 = 5;
var z3 = lineCal.calZVertical(x3);
var x4 = -5;
var z4 = lineCal.calZVertical(x4);
edgeLines.Add(new Tuple<Vector3, Vector3>(new Vector3(x3, Y, z3), new Vector3(x4, Y, z4)));
lines.Add(DisplayLineModel3D(edgeLines, YlineColor));
edgeLines.Add(lineCal.calLineOfOffset(new Tuple<Vector3, Vector3>(new Vector3(x3, Y, z3), new Vector3(x4, Y, z4)), 2));
lines.Add(DisplayLineModel3D(edgeLines, YlineColor));
edgeLines.Add(lineCal.calLineOfOffset(new Tuple<Vector3, Vector3>(new Vector3(x3, Y, z3), new Vector3(x4, Y, z4)), -2));
lines.Add(DisplayLineModel3D(edgeLines, YlineColor));
return lines;
}
public static LineGeometryModel3D ShowCircleLine(double radius = 1.0, double thickness = 1.0)
{
var Y = -0.01F;
var center = ViewportManager.CenterVector;
center.Y = Y;
return UpdateCircleGeometry(center);
}
private static LineGeometryModel3D UpdateCircleGeometry(Vector3 center, double radius = 1.0)
{
// 生成圆形线的点
int segments = 100; // 圆的细分段数
var positions = new List<Vector3>();
var indices = new List<int>();
for (int i = 0; i < segments; i++)
{
float angle = (float)(2 * Math.PI * i / segments);
float x = (float)(center.X + radius * Math.Cos(angle));
float y = (float)(center.Y);
float z = (float)(center.Z + radius * Math.Sin(angle));
positions.Add(new Vector3(x, y, z));
indices.Add(i);
indices.Add((i + 1) % segments);
}
// 更新圆形线的几何形状
return DisplayLineModel3D(positions, Color4.Black);
}
#region 私有方法
/// <summary>

@ -1,6 +1,8 @@
using System.Text.Json.Nodes;
using System.Windows.Controls;
using System.Windows.Media.Media3D;
using HelixToolkit.Wpf.SharpDX;
using MathNet.Numerics;
using SharpDX;
using SharpDX.Direct3D11;
using SparkClient.Views.UserControl.ViewportData.Entity;
@ -46,6 +48,14 @@ public class ViewportManager
/// </summary>
public static List<LineGeometryModel3D> MainModelLines = new List<LineGeometryModel3D>();
/// <summary>
/// 网格线
/// </summary>
public static List<LineGeometryModel3D> MainModelMeshLines = new List<LineGeometryModel3D>();
/// <summary>
/// 网格线(圈)
/// </summary>
public static LineGeometryModel3D MainModelCircleLine = new LineGeometryModel3D();
/// <summary>
/// 腰垂直线
/// </summary>
public static List<Tuple<Vector3, Vector3>> MainModelGirdleLines = new List<Tuple<Vector3, Vector3>>();
@ -261,10 +271,14 @@ public class ViewportManager
MainModelLighting = ViewportHelperPro.GenerateLightingForModel(_viewport);
MainModelMeshes = ViewportHelperPro.GenerateModelByEntityGroupByType(entities);
MainModelLines.AddRange(ViewportHelperPro.GentrateLineGirdleByEntity(entities));
//切换相机视角
_viewport.Camera = ViewportHelperPro.CalculateCamera(PositiveDirection, ModelBounds);
_viewport.Camera.UpDirection = new Vector3D(0, -1, 0);
_viewport.RenderHost.MSAA = MSAALevel.Maximum;
// TODO:
MainModelMeshLines.AddRange(ViewportHelperPro.ShowMeshLines(entities));
MainModelCircleLine = ViewportHelperPro.ShowCircleLine();
}
/// <summary>
@ -406,6 +420,26 @@ public class ViewportManager
}
}
public static void ShowMeshLines(bool isShow) {
if (_viewport == null) return;
if (isShow)
{
MainModelMeshLines.ForEach(e =>
{
if (!_viewport.Items.Contains(e))
_viewport.Items.Add(e);
});
if (!_viewport.Items.Contains(MainModelCircleLine))
_viewport.Items.Add(MainModelCircleLine);
}
else
{
MainModelMeshLines.ForEach(e => _viewport.Items.Remove(e));
_viewport.Items.Remove(MainModelCircleLine);
}
}
#endregion

Loading…
Cancel
Save