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. 274
      Views/UserControl/ViewportData/Helper/ViewportHelperPro.cs
  5. 98
      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 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 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 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> </ContextMenu>
</Border.ContextMenu> </Border.ContextMenu>
<hx:Viewport3DX x:Name="Viewport3Dx" ShowCoordinateSystem="True" <hx:Viewport3DX x:Name="Viewport3Dx" ShowCoordinateSystem="True"
PreviewMouseRightButtonUp="UIElement_OnPreviewMouseRightButtonUp" PreviewMouseRightButtonUp="UIElement_OnPreviewMouseRightButtonUp"
PreviewMouseRightButtonDown="UIElement_OnPreviewMouseRightButtonDown" PreviewMouseRightButtonDown="UIElement_OnPreviewMouseRightButtonDown"
PreviewMouseMove="Viewport3Dx_OnPreviewMouseMove" PreviewMouseMove="Viewport3Dx_OnPreviewMouseMove"
MouseLeftButtonDown="Viewport3Dx_OnMouseLeftButtonDown"> MouseLeftButtonDown="Viewport3Dx_MouseLeftButtonDown"
MouseDoubleClick="Viewport3Dx_OnMouseLeftButtonDown">
<hx:Viewport3DX.EffectsManager><hx:EffectsManager ></hx:EffectsManager></hx:Viewport3DX.EffectsManager> <hx:Viewport3DX.EffectsManager><hx:EffectsManager ></hx:EffectsManager></hx:Viewport3DX.EffectsManager>
<hx:Viewport3DX.InputBindings> <hx:Viewport3DX.InputBindings>
<KeyBinding Key="B" Command="hx:ViewportCommands.BackView" /> <KeyBinding Key="B" Command="hx:ViewportCommands.BackView" />
@ -85,8 +87,12 @@
<KeyBinding Command="hx:ViewportCommands.ZoomExtents" Gesture="Control+E" /> <KeyBinding Command="hx:ViewportCommands.ZoomExtents" Gesture="Control+E" />
<MouseBinding Command="hx:ViewportCommands.Rotate" Gesture="RightClick" /> <MouseBinding Command="hx:ViewportCommands.Rotate" Gesture="RightClick" />
<MouseBinding Command="hx:ViewportCommands.Zoom" Gesture="MiddleClick" /> <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:Viewport3DX.InputBindings>
<hx:AxisPlaneGridModel3D
AutoSpacing="true"
RenderShadowMap="False"
Offset="0" />
</hx:Viewport3DX> </hx:Viewport3DX>
</Border> </Border>
<Grid Grid.Row="2" Height="100"> <Grid Grid.Row="2" Height="100">

@ -15,6 +15,7 @@ using HelixToolkit.Wpf.SharpDX;
using SharpDX; using SharpDX;
using SharpDX.Direct3D11; using SharpDX.Direct3D11;
using SharpDX.DXGI; using SharpDX.DXGI;
using MathNet.Numerics;
namespace SparkClient.Views.UserControl; namespace SparkClient.Views.UserControl;
@ -60,6 +61,10 @@ public partial class Viewport3D
var a = Viewport3Dx.Items; 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.DoubleClickSelectShowPlaneType = checkResult;
ViewportManager.ResetChooseAddModels(); 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; break;
} }
} }
@ -578,4 +594,16 @@ public partial class Viewport3D
//Viewport3Dx.ShowFrameRate = !Viewport3Dx.ShowFrameRate; //Viewport3Dx.ShowFrameRate = !Viewport3Dx.ShowFrameRate;
//Viewport3Dx.ShowTriangleCountInfo = !Viewport3Dx.ShowTriangleCountInfo; //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,13 +21,15 @@ using SparkClient.Views.UserControl.ViewportData.Enum;
using SparkClient.Views.UserControl.ViewportData.Entity; using SparkClient.Views.UserControl.ViewportData.Entity;
using Color = SharpDX.Color; using Color = SharpDX.Color;
using GeometryModel3D = HelixToolkit.Wpf.SharpDX.GeometryModel3D; using GeometryModel3D = HelixToolkit.Wpf.SharpDX.GeometryModel3D;
using NPOI.SS.Formula.Functions;
using MeshGeometry3D = HelixToolkit.Wpf.SharpDX.MeshGeometry3D;
namespace SparkClient.Views.UserControl.ViewportData.Helper; namespace SparkClient.Views.UserControl.ViewportData.Helper;
public class ViewportHelperPro public class ViewportHelperPro
{ {
private static readonly ILog Logger = LogManager.GetLogger(typeof(ViewportHelperPro)); private static readonly ILog Logger = LogManager.GetLogger(typeof(ViewportHelperPro));
/// <summary> /// <summary>
/// 对指定类型的面进行标色 /// 对指定类型的面进行标色
/// </summary> /// </summary>
/// <param name="planeType"></param> /// <param name="planeType"></param>
@ -35,12 +37,12 @@ public class ViewportHelperPro
/// <returns></returns> /// <returns></returns>
public static MeshGeometryModel3D GenerateTypePanelHot(PlaneType planeType, Color4? color = null) public static MeshGeometryModel3D GenerateTypePanelHot(PlaneType planeType, Color4? color = null)
{ {
var entities = ViewportManager.ViewportTriangle.Where(e=>e.PlaneType==planeType).ToList(); var entities = ViewportManager.ViewportTriangle.Where(e => e.PlaneType == planeType).ToList();
return GenerateModelByEntity(entities, color??ViewportManager.ColorConfig.ErrFacetColor); return GenerateModelByEntity(entities, color ?? ViewportManager.ColorConfig.ErrFacetColor);
} }
#region 已经确定和调整好的方法 #region 已经确定和调整好的方法
/// <summary> /// <summary>
/// 通过三角形实体集合生成面模型(生成并添加) /// 通过三角形实体集合生成面模型(生成并添加)
/// </summary> /// </summary>
/// <param name="viewport"></param> /// <param name="viewport"></param>
@ -62,11 +64,11 @@ public class ViewportHelperPro
{ {
var meshBuilder = new MeshBuilder(true, false); var meshBuilder = new MeshBuilder(true, false);
foreach (var entity in entities) foreach (var entity in entities)
{ {
if (entity.PlaneType == PlaneType.Girdle) if (entity.PlaneType == PlaneType.Girdle)
{ {
meshBuilder.AddTriangleFan(new List<Vector3>() { entity.Point1, entity.Point2, entity.Point3 }, meshBuilder.AddTriangleFan(new List<Vector3>() { entity.Point1, entity.Point2, entity.Point3 },
new List<Vector3>() { new Vector3(0,0,0), new Vector3(0,0,0), new Vector3(0,0,0) }); new List<Vector3>() { new Vector3(0, 0, 0), new Vector3(0, 0, 0), new Vector3(0, 0, 0) });
} }
else else
{ {
@ -74,11 +76,11 @@ public class ViewportHelperPro
} }
} }
var mesh = meshBuilder.ToMeshGeometry3D(); var mesh = meshBuilder.ToMeshGeometry3D();
var material = new PBRMaterial var material = new PBRMaterial
{ {
AlbedoColor = new Color4(0.0f, 0f,0f,1f), // 黑色,避免其他光照影响 AlbedoColor = new Color4(0.0f, 0f, 0f, 1f), // 黑色,避免其他光照影响
EmissiveColor =color ?? ViewportManager.ColorConfig.MainFacetColor , // LightGray #D3D3D3 EmissiveColor = color ?? ViewportManager.ColorConfig.MainFacetColor, // LightGray #D3D3D3
MetallicFactor = 0.0, // 非金属 MetallicFactor = 0.0, // 非金属
RoughnessFactor = 1.0, // 高粗糙度,避免反射效果 RoughnessFactor = 1.0, // 高粗糙度,避免反射效果
ReflectanceFactor = 0.0, // 无反射 ReflectanceFactor = 0.0, // 无反射
@ -99,7 +101,7 @@ public class ViewportHelperPro
Material = material, Material = material,
}; };
} }
/// <summary> /// <summary>
/// 通过三角形实体集合生成面模型(只生成不添加) /// 通过三角形实体集合生成面模型(只生成不添加)
/// </summary> /// </summary>
@ -111,7 +113,7 @@ public class ViewportHelperPro
var groupedDict = entities var groupedDict = entities
.GroupBy(e => e.PlaneType) .GroupBy(e => e.PlaneType)
.ToDictionary(g => g.Key, g => g.ToList()); .ToDictionary(g => g.Key, g => g.ToList());
var result = new List<MeshGeometryModel3D>(); var result = new List<MeshGeometryModel3D>();
foreach (var group in groupedDict) foreach (var group in groupedDict)
{ {
@ -128,7 +130,7 @@ public class ViewportHelperPro
{ {
case PlaneType.Girdle: case PlaneType.Girdle:
return ViewportManager.ColorConfig.GirdleFacetColor; return ViewportManager.ColorConfig.GirdleFacetColor;
case PlaneType.TableFacet : case PlaneType.TableFacet:
return ViewportManager.ColorConfig.TableFacetColor; return ViewportManager.ColorConfig.TableFacetColor;
case PlaneType.UpperMainFacet: case PlaneType.UpperMainFacet:
return ViewportManager.ColorConfig.UpperMainFacetColor; return ViewportManager.ColorConfig.UpperMainFacetColor;
@ -136,12 +138,12 @@ public class ViewportHelperPro
return ViewportManager.ColorConfig.StarFacetColor; return ViewportManager.ColorConfig.StarFacetColor;
case PlaneType.UpperGirdleFacet: case PlaneType.UpperGirdleFacet:
return ViewportManager.ColorConfig.UpperGirdleFacetColor; return ViewportManager.ColorConfig.UpperGirdleFacetColor;
case PlaneType.PavilionMainFacet: case PlaneType.PavilionMainFacet:
return ViewportManager.ColorConfig.PavilionFacetColor; return ViewportManager.ColorConfig.PavilionFacetColor;
case PlaneType.LowerGirdleFact: case PlaneType.LowerGirdleFact:
return ViewportManager.ColorConfig.LowerGirdleFacetColor; return ViewportManager.ColorConfig.LowerGirdleFacetColor;
case PlaneType.Culet: case PlaneType.Culet:
return ViewportManager.ColorConfig.CuletFacetColor; return ViewportManager.ColorConfig.CuletFacetColor;
} }
return null; return null;
@ -177,12 +179,12 @@ public class ViewportHelperPro
{ {
if (viewport == null) if (viewport == null)
viewport = ViewportManager.GetViewport3D(); viewport = ViewportManager.GetViewport3D();
var generationTask = VideoHelper.StartGenerationAndRotation(viewport); var generationTask = VideoHelper.StartGenerationAndRotation(viewport);
List<PngBitmapEncoder> pngList = await generationTask; List<PngBitmapEncoder> pngList = await generationTask;
await VideoHelper.CreateVideoFromPngListAsync(pngList, filePath); await VideoHelper.CreateVideoFromPngListAsync(pngList, filePath);
} }
/// <summary> /// <summary>
@ -200,7 +202,7 @@ public class ViewportHelperPro
writer.WriteLine("solid exportedModel"); writer.WriteLine("solid exportedModel");
foreach (var model in viewport.Items.OfType<MeshGeometryModel3D>()) foreach (var model in viewport.Items.OfType<MeshGeometryModel3D>())
{ {
if (model.Geometry is HelixToolkit.Wpf.SharpDX.Geometry3D geometry) if (model.Geometry is HelixToolkit.Wpf.SharpDX.Geometry3D geometry)
{ {
var positions = geometry.Positions; var positions = geometry.Positions;
@ -241,7 +243,7 @@ public class ViewportHelperPro
/// </summary> /// </summary>
/// <param name="viewport"></param> /// <param name="viewport"></param>
/// <param name="filePath"></param> /// <param name="filePath"></param>
public static async Task ExportModelsToStlASync( string filePath) public static async Task ExportModelsToStlASync(string filePath)
{ {
Viewport3DX viewport = ViewportManager.GetViewport3D(); Viewport3DX viewport = ViewportManager.GetViewport3D();
@ -249,7 +251,7 @@ public class ViewportHelperPro
List<Tuple<IList<Vector3>, IList<int>>> geometries = new List<Tuple<IList<Vector3>, IList<int>>>(); List<Tuple<IList<Vector3>, IList<int>>> geometries = new List<Tuple<IList<Vector3>, IList<int>>>();
// 在 UI 线程中收集几何信息 // 在 UI 线程中收集几何信息
await Application.Current.Dispatcher.InvokeAsync(() => await Application.Current.Dispatcher.InvokeAsync(() =>
{ {
foreach (var model in viewport.Items.OfType<MeshGeometryModel3D>()) foreach (var model in viewport.Items.OfType<MeshGeometryModel3D>())
{ {
@ -341,7 +343,7 @@ public class ViewportHelperPro
selFaceVector.Add(entity.Point3); selFaceVector.Add(entity.Point3);
} }
HashSet<Vector3> uniqueVectors = new HashSet<Vector3>(selFaceVector); HashSet<Vector3> uniqueVectors = new HashSet<Vector3>(selFaceVector);
for (int i = 0; i < selFaceVector.ToList().Count - 1; i++) for (int i = 0; i < selFaceVector.ToList().Count - 1; i++)
{ {
var nowItem = selFaceVector.ToList()[i]; var nowItem = selFaceVector.ToList()[i];
@ -350,11 +352,11 @@ public class ViewportHelperPro
if (IsLineSegmentParallelToYAxis(line)) if (IsLineSegmentParallelToYAxis(line))
{ {
lines.Add(line); lines.Add(line);
result.Add(DisplayLineModel3D(new List<Vector3>(){nowItem,nextItem }, color??ViewportManager.ColorConfig.MainBorderColor, thickness)); result.Add(DisplayLineModel3D(new List<Vector3>() { nowItem, nextItem }, color ?? ViewportManager.ColorConfig.MainBorderColor, thickness));
} }
} }
} }
CalculateLineSegmentStats(lines, out ViewportManager.MainModelGirdleMaxLines, out ViewportManager.MainModelGirdleMinLines, out ViewportManager.MainModelGirdleAvgLines); CalculateLineSegmentStats(lines, out ViewportManager.MainModelGirdleMaxLines, out ViewportManager.MainModelGirdleMinLines, out ViewportManager.MainModelGirdleAvgLines);
ViewportManager.MainModelGirdleLines = lines; ViewportManager.MainModelGirdleLines = lines;
return result; return result;
@ -374,12 +376,12 @@ public class ViewportHelperPro
List<Viewport3DTriangleEntity> waistList = entities List<Viewport3DTriangleEntity> waistList = entities
.Where(entity => entity.PlaneType == PlaneType.Girdle) .Where(entity => entity.PlaneType == PlaneType.Girdle)
.ToList(); .ToList();
Dictionary<string, List<Viewport3DTriangleEntity>> feactList = entities Dictionary<string, List<Viewport3DTriangleEntity>> feactList = entities
.Where(entity => entity.PlaneType != PlaneType.Girdle) .Where(entity => entity.PlaneType != PlaneType.Girdle)
.GroupBy(entity => entity.PlaneCode) .GroupBy(entity => entity.PlaneCode)
.ToDictionary(group => group.Key, group => group.ToList()); .ToDictionary(group => group.Key, group => group.ToList());
foreach (var item in feactList) foreach (var item in feactList)
{ {
//GenerateLineTextModelByEntity(viewport, item.Value, Viewport3DManager.Gray); //GenerateLineTextModelByEntity(viewport, item.Value, Viewport3DManager.Gray);
@ -390,9 +392,9 @@ public class ViewportHelperPro
temp.Add(entity.Point2); temp.Add(entity.Point2);
temp.Add(entity.Point3); temp.Add(entity.Point3);
} }
result.Add(DisplayLineModel3D(VectorClockwiseSort(new HashSet<Vector3>(temp).ToList()), color??ViewportManager.ColorConfig.MainBorderColor, thickness)); result.Add(DisplayLineModel3D(VectorClockwiseSort(new HashSet<Vector3>(temp).ToList()), color ?? ViewportManager.ColorConfig.MainBorderColor, thickness));
} }
//腰 - 特殊 //腰 - 特殊
List<Vector3> selFaceVector = new List<Vector3>(); List<Vector3> selFaceVector = new List<Vector3>();
if (waistList.Count > 0) if (waistList.Count > 0)
@ -412,28 +414,28 @@ public class ViewportHelperPro
ViewportManager.GirdleBottomLines.Clear(); ViewportManager.GirdleBottomLines.Clear();
foreach (var vector in uniqueVectors) foreach (var vector in uniqueVectors)
{ {
if(vector.Y < mid) if (vector.Y < mid)
ViewportManager.GirdleBottomLines.Add(vector); ViewportManager.GirdleBottomLines.Add(vector);
else else
ViewportManager.GirdleTopLines.Add(vector); ViewportManager.GirdleTopLines.Add(vector);
} }
// result.Add(DisplayLineModel3D( VectorClockwiseSort(ViewportManager.GirdleBottomLines), color??ViewportManager.ColorConfig.MainBorderColor, thickness)); // result.Add(DisplayLineModel3D( VectorClockwiseSort(ViewportManager.GirdleBottomLines), color??ViewportManager.ColorConfig.MainBorderColor, thickness));
// result.Add(DisplayLineModel3D( VectorClockwiseSort(ViewportManager.GirdleTopLines), color??ViewportManager.ColorConfig.MainBorderColor, thickness)); // result.Add(DisplayLineModel3D( VectorClockwiseSort(ViewportManager.GirdleTopLines), color??ViewportManager.ColorConfig.MainBorderColor, thickness));
} }
return result; return result;
} }
public static List<Viewport3DTriangleEntity> GenerateLineTextModelsByType(PlaneType type, Color4? textColor = null, public static List<Viewport3DTriangleEntity> GenerateLineTextModelsByType(PlaneType type, Color4? textColor = null,
bool showAll = false) bool showAll = false)
{ {
List<Viewport3DTriangleEntity> entities = new List<Viewport3DTriangleEntity>(); List<Viewport3DTriangleEntity> entities = new List<Viewport3DTriangleEntity>();
string planCode = ""; string planCode = "";
ViewportManager.ViewportTriangle.ForEach(e => ViewportManager.ViewportTriangle.ForEach(e =>
{ {
if (e.PlaneType == type && (e.PlaneCode==planCode || string.IsNullOrEmpty(planCode))) if (e.PlaneType == type && (e.PlaneCode == planCode || string.IsNullOrEmpty(planCode)))
{ {
planCode = e.PlaneCode; planCode = e.PlaneCode;
entities.Add(e); entities.Add(e);
@ -449,12 +451,12 @@ public class ViewportHelperPro
/// <param name="entities">三角形集合</param> /// <param name="entities">三角形集合</param>
/// <param name="valKey">指定数据集</param> /// <param name="valKey">指定数据集</param>
/// <returns></returns> /// <returns></returns>
public static List<GeometryModel3D> GenerateLineTextModels(List<Viewport3DTriangleEntity> entities, string valKey = "") public static List<GeometryModel3D> GenerateLineTextModels(List<Viewport3DTriangleEntity> entities, string valKey = "")
{ {
Logger.Info("【面文本生成】开始生成面相关文本信息"); Logger.Info("【面文本生成】开始生成面相关文本信息");
var selFacet = entities; var selFacet = entities;
var selFacetType = entities.First().PlaneType; var selFacetType = entities.First().PlaneType;
var result = new List<GeometryModel3D>(); var result = new List<GeometryModel3D>();
if (selFacetType == PlaneType.Girdle && string.IsNullOrWhiteSpace(valKey)) if (selFacetType == PlaneType.Girdle && string.IsNullOrWhiteSpace(valKey))
{ {
@ -474,11 +476,11 @@ public class ViewportHelperPro
var groupedDic = facetTypeAll.GroupBy(entity => entity.PlaneCode) var groupedDic = facetTypeAll.GroupBy(entity => entity.PlaneCode)
.ToDictionary(group => group.Key, group => group.ToList()); .ToDictionary(group => group.Key, group => group.ToList());
Logger.Info($"【面文本生成】 腰由{groupedDic.Count}个面组成"); Logger.Info($"【面文本生成】 腰由{groupedDic.Count}个面组成");
var selPlaneCode = entities.First().PlaneCode; var selPlaneCode = entities.First().PlaneCode;
Logger.Info($"【面文本生成】 当前选择{selPlaneCode}"); Logger.Info($"【面文本生成】 当前选择{selPlaneCode}");
List<Vector3> facetPoints = new List<Vector3>(); List<Vector3> facetPoints = new List<Vector3>();
entities.ForEach(e => { facetPoints.Add(e.Point1); facetPoints.Add(e.Point2); facetPoints.Add(e.Point3); }); entities.ForEach(e => { facetPoints.Add(e.Point1); facetPoints.Add(e.Point2); facetPoints.Add(e.Point3); });
var facetIndex = -1; var facetIndex = -1;
int.TryParse(selPlaneCode.Split("_")[1], out facetIndex); int.TryParse(selPlaneCode.Split("_")[1], out facetIndex);
@ -495,35 +497,35 @@ public class ViewportHelperPro
case 0: case 0:
case 3: case 3:
var longestLine1 = GetLongestOrShortestLineSegment(facetPoints, returnLongest: true); var longestLine1 = GetLongestOrShortestLineSegment(facetPoints, returnLongest: true);
result.Add(DisplayLineModel3D(new List<Tuple<Vector3,Vector3>>(){longestLine1}, new Color4(1f, 0, 0, 1f) , 2f)); result.Add(DisplayLineModel3D(new List<Tuple<Vector3, Vector3>>() { longestLine1 }, new Color4(1f, 0, 0, 1f), 2f));
break; break;
case 1: case 1:
case 2: case 2:
var longestLine2 = GetLongestOrShortestLineSegment(facetPoints, returnLongest: false); var longestLine2 = GetLongestOrShortestLineSegment(facetPoints, returnLongest: false);
result.Add(DisplayLineModel3D(new List<Tuple<Vector3,Vector3>>(){longestLine2}, new Color4(1f, 0, 0, 1f) , 2f)); result.Add(DisplayLineModel3D(new List<Tuple<Vector3, Vector3>>() { longestLine2 }, new Color4(1f, 0, 0, 1f), 2f));
break; break;
} }
//开始找值 //开始找值
string param = string.Empty; string param = string.Empty;
var valueIndex = 0; var valueIndex = 0;
if (facetIndex % 8 == 0 || (facetIndex+1) % 8 == 0) if (facetIndex % 8 == 0 || (facetIndex + 1) % 8 == 0)
{ {
//上腰面 //上腰面
Logger.Info($"【面文本生成】 腰面值 波峰【上腰面】"); Logger.Info($"【面文本生成】 腰面值 波峰【上腰面】");
valueIndex = (int)Math.Ceiling(facetIndex / 8.0) == 8 ? 0 : (int)Math.Ceiling(facetIndex / 8.0); valueIndex = (int)Math.Ceiling(facetIndex / 8.0) == 8 ? 0 : (int)Math.Ceiling(facetIndex / 8.0);
param = "GIRDLE_BONE"; param = "GIRDLE_BONE";
}else if (linePointType == 3 || linePointType == 0) } else if (linePointType == 3 || linePointType == 0)
{ {
//风筝面 //风筝面
Logger.Info($"【面文本生成】 腰面值 波峰【风筝面】"); Logger.Info($"【面文本生成】 腰面值 波峰【风筝面】");
valueIndex = (facetIndex / 8) ; valueIndex = (facetIndex / 8);
param = "GIRDLE_BEZEL"; param = "GIRDLE_BEZEL";
} }
else else
{ {
//腰厚比 //腰厚比
Logger.Info($"【面文本生成】 腰面值 波峰【腰厚比】"); Logger.Info($"【面文本生成】 腰面值 波峰【腰厚比】");
valueIndex = (facetIndex / 4) ; valueIndex = (facetIndex / 4);
param = "GIRDLE_VALLEY"; param = "GIRDLE_VALLEY";
} }
@ -542,7 +544,7 @@ public class ViewportHelperPro
return result; return result;
} }
Logger.Info($"【面文本生成】 {param}_DETAIL.{param}_{valueIndex} ==={paramValue}"); Logger.Info($"【面文本生成】 {param}_DETAIL.{param}_{valueIndex} ==={paramValue}");
var valueFloat = (Math.Floor(float.Parse(paramValue.ToString())*1000)/10).ToString(); var valueFloat = (Math.Floor(float.Parse(paramValue.ToString()) * 1000) / 10).ToString();
Logger.Info($"【面文本生成】 {valueFloat} -- {valueIndex}"); Logger.Info($"【面文本生成】 {valueFloat} -- {valueIndex}");
var facetTextPoint = GetOffsetCenter(facetPoints, ViewportManager.CenterVector); var facetTextPoint = GetOffsetCenter(facetPoints, ViewportManager.CenterVector);
result.Add(DisplayText3D($"{valueFloat}", facetTextPoint)); result.Add(DisplayText3D($"{valueFloat}", facetTextPoint));
@ -567,7 +569,7 @@ public class ViewportHelperPro
// */ // */
// //
// } // }
}else if (selFacetType == PlaneType.Girdle && !string.IsNullOrWhiteSpace(valKey)) } else if (selFacetType == PlaneType.Girdle && !string.IsNullOrWhiteSpace(valKey))
{ {
Logger.Info($"【面文本生成】 命中面{selFacetType},是腰,显示值{valKey}"); Logger.Info($"【面文本生成】 命中面{selFacetType},是腰,显示值{valKey}");
/*** /***
@ -584,11 +586,11 @@ public class ViewportHelperPro
{ {
switch (valKey) switch (valKey)
{ {
case "GIRDLE_BEZEL": if(i%8==4)resultDic.Add($"0_{i}", groupedDic[$"0_{i}"]); case "GIRDLE_BEZEL": if (i % 8 == 4) resultDic.Add($"0_{i}", groupedDic[$"0_{i}"]);
break; break;
case "GIRDLE_BONE": if(i%8==0)resultDic.Add($"0_{i}", groupedDic[$"0_{i}"]); case "GIRDLE_BONE": if (i % 8 == 0) resultDic.Add($"0_{i}", groupedDic[$"0_{i}"]);
break; break;
case "GIRDLE_VALLEY": if(i%4==2)resultDic.Add($"0_{i}", groupedDic[$"0_{i}"]); case "GIRDLE_VALLEY": if (i % 4 == 2) resultDic.Add($"0_{i}", groupedDic[$"0_{i}"]);
break; break;
} }
} }
@ -601,12 +603,12 @@ public class ViewportHelperPro
foreach (var dic in resultDic) foreach (var dic in resultDic)
{ {
//高亮四边形左边的线,并绑定值 //高亮四边形左边的线,并绑定值
List<Vector3> facetPoints = new List<Vector3>(); List<Vector3> facetPoints = new List<Vector3>();
dic.Value.ForEach(e => { facetPoints.Add(e.Point1); facetPoints.Add(e.Point2); facetPoints.Add(e.Point3); }); dic.Value.ForEach(e => { facetPoints.Add(e.Point1); facetPoints.Add(e.Point2); facetPoints.Add(e.Point3); });
//高亮的线 //高亮的线
var showLine = GetLeftParallelLineSegment(facetPoints); var showLine = GetLeftParallelLineSegment(facetPoints);
if(showLine == null)continue; if (showLine == null) continue;
//文字显示位置 //文字显示位置
var facetTextPoint = GetOffsetCenter(facetPoints, ViewportManager.CenterVector); var facetTextPoint = GetOffsetCenter(facetPoints, ViewportManager.CenterVector);
var resIndex = resultDic.Keys.ToList().IndexOf(dic.Key); var resIndex = resultDic.Keys.ToList().IndexOf(dic.Key);
@ -625,11 +627,11 @@ public class ViewportHelperPro
Logger.Info($"【面文本生成】 {valKey}_DETAIL.{valKey}_{resIndex} Key不存在"); Logger.Info($"【面文本生成】 {valKey}_DETAIL.{valKey}_{resIndex} Key不存在");
return result; return result;
} }
result.Add(DisplayLineModel3D(new List<Tuple<Vector3,Vector3>>(){showLine}, new Color4(1f, 0, 0, 1f) , 2f)); result.Add(DisplayLineModel3D(new List<Tuple<Vector3, Vector3>>() { showLine }, new Color4(1f, 0, 0, 1f), 2f));
var valueFloat = ValueFormat(paramValue.ToString(),valKey); var valueFloat = ValueFormat(paramValue.ToString(), valKey);
result.Add(DisplayText3D($" {resIndex} \r\n {valueFloat}", facetTextPoint)); result.Add(DisplayText3D($" {resIndex} \r\n {valueFloat}", facetTextPoint));
} }
} }
else else
{ {
@ -647,14 +649,14 @@ public class ViewportHelperPro
var key = kv.Key; var key = kv.Key;
var facetIndex = -1; var facetIndex = -1;
int.TryParse(key.Split("_")[1], out facetIndex); int.TryParse(key.Split("_")[1], out facetIndex);
List<Vector3> facetPoints = new List<Vector3>(); List<Vector3> facetPoints = new List<Vector3>();
value.ForEach(e => { facetPoints.Add(e.Point1); facetPoints.Add(e.Point2); facetPoints.Add(e.Point3); }); value.ForEach(e => { facetPoints.Add(e.Point1); facetPoints.Add(e.Point2); facetPoints.Add(e.Point3); });
var param = string.IsNullOrWhiteSpace(valKey)? ViewportManager.DicFacetToValueParam.ContainsKey(selFacetType) ? ViewportManager.DicFacetToValueParam[selFacetType] : null : valKey; var param = string.IsNullOrWhiteSpace(valKey) ? ViewportManager.DicFacetToValueParam.ContainsKey(selFacetType) ? ViewportManager.DicFacetToValueParam[selFacetType] : null : valKey;
if (param == null) if (param == null)
{ {
continue; continue;
} }
if (groupedDic.Count == 1) if (groupedDic.Count == 1)
{ {
var paramValue = ViewportManager.DiamondData[$"{param}"]; var paramValue = ViewportManager.DiamondData[$"{param}"];
@ -663,12 +665,12 @@ public class ViewportHelperPro
Logger.Info($"【面文本生成】 {param} Key不存在"); Logger.Info($"【面文本生成】 {param} Key不存在");
continue; continue;
} }
var valueFloat = ValueFormat(paramValue.ToString(),param); var valueFloat = ValueFormat(paramValue.ToString(), param);
Logger.Info($"【面文本生成】 {valueFloat} -- {facetIndex}"); Logger.Info($"【面文本生成】 {valueFloat} -- {facetIndex}");
var facetTextPoint = GetOffsetCenter(facetPoints, ViewportManager.CenterVector); var facetTextPoint = GetOffsetCenter(facetPoints, ViewportManager.CenterVector);
result.Add(DisplayText3D($"{valueFloat}", facetTextPoint)); result.Add(DisplayText3D($"{valueFloat}", facetTextPoint));
}else if (groupedDic.Count == 16) } else if (groupedDic.Count == 16)
{ {
facetIndex += 1; facetIndex += 1;
valueIndex = facetIndex == 16 ? 1 : facetIndex % 2 == 0 ? valueIndex + 1 : valueIndex; valueIndex = facetIndex == 16 ? 1 : facetIndex % 2 == 0 ? valueIndex + 1 : valueIndex;
@ -687,15 +689,15 @@ public class ViewportHelperPro
} }
Logger.Info($"【面文本生成】 {param}_DETAIL.{param}_{valueIndex} ==={paramValue}"); Logger.Info($"【面文本生成】 {param}_DETAIL.{param}_{valueIndex} ==={paramValue}");
var valueFloat = ValueFormat(paramValue.ToString(),param); var valueFloat = ValueFormat(paramValue.ToString(), param);
Logger.Info($"【面文本生成】 {valueFloat} -- {valueIndex}"); Logger.Info($"【面文本生成】 {valueFloat} -- {valueIndex}");
var facetTextPoint = GetOffsetCenter(facetPoints, ViewportManager.CenterVector); var facetTextPoint = GetOffsetCenter(facetPoints, ViewportManager.CenterVector);
result.Add(DisplayText3D($" {facetIndex} \r\n {valueFloat}", new Vector3(facetTextPoint.X, facetTextPoint.Y+0.1f, facetTextPoint.Z))); result.Add(DisplayText3D($" {facetIndex} \r\n {valueFloat}", new Vector3(facetTextPoint.X, facetTextPoint.Y + 0.1f, facetTextPoint.Z)));
} else if (ViewportManager.DiamondData.Count > 1 && facetIndex != -1) } else if (ViewportManager.DiamondData.Count > 1 && facetIndex != -1)
{ {
facetIndex += 1; facetIndex += 1;
var detail = ViewportManager.DiamondData[$"{param}_DETAIL"]; var detail = ViewportManager.DiamondData[$"{param}_DETAIL"];
if (detail == null) if (detail == null)
{ {
@ -711,7 +713,7 @@ public class ViewportHelperPro
} }
Logger.Info($"【面文本生成】 {param}_DETAIL.{param}_{facetIndex} ==={paramValue}"); Logger.Info($"【面文本生成】 {param}_DETAIL.{param}_{facetIndex} ==={paramValue}");
var valueFloat = ValueFormat(paramValue.ToString(),param); var valueFloat = ValueFormat(paramValue.ToString(), param);
Logger.Info($"【面文本生成】 {valueFloat} -- {facetIndex}"); Logger.Info($"【面文本生成】 {valueFloat} -- {facetIndex}");
var facetTextPoint = GetOffsetCenter(facetPoints, ViewportManager.CenterVector); var facetTextPoint = GetOffsetCenter(facetPoints, ViewportManager.CenterVector);
result.Add(DisplayText3D($" {facetIndex} \r\n {valueFloat}", facetTextPoint)); result.Add(DisplayText3D($" {facetIndex} \r\n {valueFloat}", facetTextPoint));
@ -733,7 +735,7 @@ public class ViewportHelperPro
* -id的文本 * -id的文本
* +0.1"个单位 显示文本 * +0.1"个单位 显示文本
*/ */
// var selFaceVector = entities // var selFaceVector = entities
// .SelectMany(entity => new[] { entity.Point1, entity.Point2, entity.Point3 }) // .SelectMany(entity => new[] { entity.Point1, entity.Point2, entity.Point3 })
// .Distinct() // .Distinct()
@ -760,7 +762,7 @@ public class ViewportHelperPro
// } // }
} }
return result; return result;
} }
@ -770,10 +772,10 @@ public class ViewportHelperPro
/// <param name="triangleCode">三角形ID</param> /// <param name="triangleCode">三角形ID</param>
/// <param name="selType">生成范围</param> /// <param name="selType">生成范围</param>
/// <returns></returns> /// <returns></returns>
public static List<GeometryModel3D> GentrateChosenView(string triangleCode, string valKey = "", params SelShowType[] selType) public static List<GeometryModel3D> GentrateChosenView(string triangleCode, string valKey = "", params SelShowType[] selType)
{ {
var res = ViewportManager.ViewportTriangle.Find(e => triangleCode.Equals(e.TriangleCode)); var res = ViewportManager.ViewportTriangle.Find(e => triangleCode.Equals(e.TriangleCode));
if(res != null) if (res != null)
return GentrateChosenView(res, valKey, selType); return GentrateChosenView(res, valKey, selType);
return new List<GeometryModel3D>(); return new List<GeometryModel3D>();
} }
@ -797,12 +799,12 @@ public class ViewportHelperPro
throw new Exception("Invalid SelShowType collection"); throw new Exception("Invalid SelShowType collection");
} }
List<GeometryModel3D> result = new List<GeometryModel3D>(); List<GeometryModel3D> result = new List<GeometryModel3D>();
//选中的面 //选中的面
var selPanel = ViewportManager.ViewportTriangle.Where(e => entity.PlaneCode.Equals(e.PlaneCode)).ToList(); var selPanel = ViewportManager.ViewportTriangle.Where(e => entity.PlaneCode.Equals(e.PlaneCode)).ToList();
//选中同类的面 //选中同类的面
var selPanelType = ViewportManager.ViewportTriangle.Where(e => entity.PlaneType.Equals(e.PlaneType)).ToList(); var selPanelType = ViewportManager.ViewportTriangle.Where(e => entity.PlaneType.Equals(e.PlaneType)).ToList();
selPanel.ForEach(e=>selPanelType.Remove(e)); selPanel.ForEach(e => selPanelType.Remove(e));
foreach (var type in selType) foreach (var type in selType)
{ {
switch (type) switch (type)
@ -826,7 +828,7 @@ public class ViewportHelperPro
break; break;
case SelShowType.BorderAngle: case SelShowType.BorderAngle:
//选中面 每条边向内的夹角 //选中面 每条边向内的夹角
if(PlaneType.Girdle == entity.PlaneType)break; if (PlaneType.Girdle == entity.PlaneType) break;
result.AddRange(GenerateLineAngleTextModels(selPanel)); result.AddRange(GenerateLineAngleTextModels(selPanel));
break; break;
} }
@ -835,7 +837,7 @@ public class ViewportHelperPro
return result; return result;
} }
/// <summary> /// <summary>
/// 生成线段夹角文本(不绘制) /// 生成线段夹角文本(不绘制)
/// </summary> /// </summary>
@ -901,7 +903,7 @@ public class ViewportHelperPro
ViewportManager.ClearDicModels(); ViewportManager.ClearDicModels();
// 设置旋转的中心点和旋转轴 // 设置旋转的中心点和旋转轴
var rotateTransform = new RotateTransform3D(); var rotateTransform = new RotateTransform3D();
var rotation = new AxisAngleRotation3D(axis, 0); var rotation = new AxisAngleRotation3D(axis, 0);
rotateTransform.Rotation = rotation; rotateTransform.Rotation = rotation;
rotateTransform.CenterX = ViewportManager.CenterVector.X; rotateTransform.CenterX = ViewportManager.CenterVector.X;
rotateTransform.CenterY = ViewportManager.CenterVector.Y; rotateTransform.CenterY = ViewportManager.CenterVector.Y;
@ -909,16 +911,16 @@ public class ViewportHelperPro
// 将旋转变换应用到模型 // 将旋转变换应用到模型
ViewportManager.MainModel3D.Transform = rotateTransform; ViewportManager.MainModel3D.Transform = rotateTransform;
if(hasLine) if (hasLine)
ViewportManager.MainModelLines.ForEach(e => e.Transform = rotateTransform); ViewportManager.MainModelLines.ForEach(e => e.Transform = rotateTransform);
double currentAngle = rotation.Angle; double currentAngle = rotation.Angle;
// 创建旋转动画 // 创建旋转动画
var rotateAnimation = new DoubleAnimation var rotateAnimation = new DoubleAnimation
{ {
From = currentAngle, From = currentAngle,
To = to + currentAngle, To = to + currentAngle,
Duration = new Duration(TimeSpan.FromSeconds(speed)), Duration = new Duration(TimeSpan.FromSeconds(speed)),
FillBehavior = FillBehavior.HoldEnd FillBehavior = FillBehavior.HoldEnd
}; };
@ -938,11 +940,11 @@ public class ViewportHelperPro
var billboardText = new BillboardText3D(); var billboardText = new BillboardText3D();
billboardText.TextInfo.Add(new TextInfo(text, position) billboardText.TextInfo.Add(new TextInfo(text, position)
{ {
Foreground = color??ViewportManager.ColorConfig.SelFontColor, Foreground = color ?? ViewportManager.ColorConfig.SelFontColor,
Scale = 0.8f, Scale = 0.8f,
VerticalAlignment = BillboardVerticalAlignment.Center, VerticalAlignment = BillboardVerticalAlignment.Center,
HorizontalAlignment = BillboardHorizontalAlignment.Center HorizontalAlignment = BillboardHorizontalAlignment.Center
}); });
billboardTextModel.Geometry = billboardText; billboardTextModel.Geometry = billboardText;
return billboardTextModel; return billboardTextModel;
@ -978,8 +980,8 @@ public class ViewportHelperPro
SlopeScaledDepthBias = 1.0f, SlopeScaledDepthBias = 1.0f,
IsDepthClipEnabled = true IsDepthClipEnabled = true
}; };
return billboardTextModel; return billboardTextModel;
} }
/// <summary> /// <summary>
@ -998,7 +1000,7 @@ public class ViewportHelperPro
var nowItem = points[i]; var nowItem = points[i];
var nextItem = points[i + 1]; var nextItem = points[i + 1];
edgeLines.Add(new Tuple<Vector3, Vector3>(nowItem, nextItem)); edgeLines.Add(new Tuple<Vector3, Vector3>(nowItem, nextItem));
} }
edgeLines.Add(new Tuple<Vector3, Vector3>(points.Last(), points.First())); edgeLines.Add(new Tuple<Vector3, Vector3>(points.Last(), points.First()));
return DisplayLineModel3D(edgeLines, lineColor, thickness); return DisplayLineModel3D(edgeLines, lineColor, thickness);
@ -1040,7 +1042,7 @@ public class ViewportHelperPro
FieldOfView = fieldOfView, FieldOfView = fieldOfView,
}; };
} }
/// <summary> /// <summary>
/// 绘制箭头(相机指向模型中心) /// 绘制箭头(相机指向模型中心)
/// </summary> /// </summary>
@ -1054,8 +1056,8 @@ public class ViewportHelperPro
/// <param name="padding">模型边界范围 1</param> /// <param name="padding">模型边界范围 1</param>
/// <returns></returns> /// <returns></returns>
public static MeshGeometryModel3D CreateArrow( public static MeshGeometryModel3D CreateArrow(
Vector3 cameraPosition, Vector3 cameraPosition,
Vector3 modelCenter, Vector3 modelCenter,
BoundingBox modelBounds, BoundingBox modelBounds,
float totalLength = 1.5f, // 箭头总长度 float totalLength = 1.5f, // 箭头总长度
float cylinderRatio = 0.7f,// 圆柱部分占比 float cylinderRatio = 0.7f,// 圆柱部分占比
@ -1100,7 +1102,7 @@ public class ViewportHelperPro
EmissiveColor = Color.Red // 箭头自发光颜色 EmissiveColor = Color.Red // 箭头自发光颜色
}; };
// 创建 3D 模型 // 创建 3D 模型
return new MeshGeometryModel3D return new MeshGeometryModel3D
@ -1109,8 +1111,8 @@ public class ViewportHelperPro
Material = material Material = material
}; };
} }
/// <summary> /// <summary>
/// 生成线对象 /// 生成线对象
/// </summary> /// </summary>
@ -1126,8 +1128,8 @@ public class ViewportHelperPro
{ {
lineBuilder.AddLine(line.Item1, line.Item2); lineBuilder.AddLine(line.Item1, line.Item2);
} }
var edgeLinesModel = new LineGeometryModel3D var edgeLinesModel = new LineGeometryModel3D
{ {
Geometry = lineBuilder.ToLineGeometry3D(), Geometry = lineBuilder.ToLineGeometry3D(),
@ -1144,9 +1146,9 @@ public class ViewportHelperPro
/// <returns></returns> /// <returns></returns>
public static List<Light3D> GenerateLightingForModel(Viewport3DX viewport) public static List<Light3D> GenerateLightingForModel(Viewport3DX viewport)
{ {
List<Light3D> result = new List<Light3D>(); List<Light3D> result = new List<Light3D>();
var models = viewport.Items.OfType<MeshGeometryModel3D>(); var models = viewport.Items.OfType<MeshGeometryModel3D>();
if (!models.Any()) throw new Exception("Model in view not found"); if (!models.Any()) throw new Exception("Model in view not found");
var largestModel = models var largestModel = models
@ -1184,7 +1186,7 @@ public class ViewportHelperPro
{ {
Position = corner, Position = corner,
Color = color, Color = color,
Range = (float)size.Length() Range = (float)size.Length()
}; };
result.Add(pointLight); result.Add(pointLight);
} }
@ -1208,7 +1210,7 @@ public class ViewportHelperPro
{ {
Color = Colors.LightGray Color = Colors.LightGray
}); });
result.Add(new AmbientLight3D result.Add(new AmbientLight3D
{ {
Color = Colors.Gray // 设置环境光颜色 Color = Colors.Gray // 设置环境光颜色
@ -1218,7 +1220,7 @@ public class ViewportHelperPro
result.ForEach(e => viewport.Items.Add(e)); result.ForEach(e => viewport.Items.Add(e));
return result; return result;
} }
public static Vector3 GetCenterOfTriangles(List<Viewport3DTriangleEntity> triangles) public static Vector3 GetCenterOfTriangles(List<Viewport3DTriangleEntity> triangles)
{ {
if (triangles == null || triangles.Count == 0) if (triangles == null || triangles.Count == 0)
@ -1239,7 +1241,7 @@ public class ViewportHelperPro
// 计算平均坐标 // 计算平均坐标
return total / vertexCount; return total / vertexCount;
} }
public static Vector3 CalculateCenter(List<Vector3> girdleTopLines, List<Vector3> girdleBottomLines) public static Vector3 CalculateCenter(List<Vector3> girdleTopLines, List<Vector3> girdleBottomLines)
{ {
// 计算 GirdleTopLines 的中心点 // 计算 GirdleTopLines 的中心点
@ -1274,8 +1276,80 @@ public class ViewportHelperPro
lights.ForEach(item => viewport.Items.Remove(item)); 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 私有方法 #region 私有方法
/// <summary> /// <summary>
/// 向量按中心点顺时针排序 /// 向量按中心点顺时针排序
/// </summary> /// </summary>

@ -1,6 +1,8 @@
using System.Text.Json.Nodes; using System.Text.Json.Nodes;
using System.Windows.Controls;
using System.Windows.Media.Media3D; using System.Windows.Media.Media3D;
using HelixToolkit.Wpf.SharpDX; using HelixToolkit.Wpf.SharpDX;
using MathNet.Numerics;
using SharpDX; using SharpDX;
using SharpDX.Direct3D11; using SharpDX.Direct3D11;
using SparkClient.Views.UserControl.ViewportData.Entity; using SparkClient.Views.UserControl.ViewportData.Entity;
@ -15,7 +17,7 @@ public class ViewportManager
/// 视图中三角形实体们 /// 视图中三角形实体们
/// </summary> /// </summary>
public static List<Viewport3DTriangleEntity> ViewportTriangle = new List<Viewport3DTriangleEntity>(); public static List<Viewport3DTriangleEntity> ViewportTriangle = new List<Viewport3DTriangleEntity>();
public static JsonObject DiamondData = new JsonObject(); public static JsonObject DiamondData = new JsonObject();
/// <summary> /// <summary>
/// 模型正方向(从模型中心出发的方向) /// 模型正方向(从模型中心出发的方向)
@ -46,23 +48,31 @@ public class ViewportManager
/// </summary> /// </summary>
public static List<LineGeometryModel3D> MainModelLines = new List<LineGeometryModel3D>(); public static List<LineGeometryModel3D> MainModelLines = new List<LineGeometryModel3D>();
/// <summary> /// <summary>
/// 网格线
/// </summary>
public static List<LineGeometryModel3D> MainModelMeshLines = new List<LineGeometryModel3D>();
/// <summary>
/// 网格线(圈)
/// </summary>
public static LineGeometryModel3D MainModelCircleLine = new LineGeometryModel3D();
/// <summary>
/// 腰垂直线 /// 腰垂直线
/// </summary> /// </summary>
public static List<Tuple<Vector3, Vector3>> MainModelGirdleLines = new List<Tuple<Vector3, Vector3>>(); public static List<Tuple<Vector3, Vector3>> MainModelGirdleLines = new List<Tuple<Vector3, Vector3>>();
public static Tuple<Vector3, Vector3> MainModelGirdleMaxLines = null; public static Tuple<Vector3, Vector3> MainModelGirdleMaxLines = null;
public static Tuple<Vector3, Vector3> MainModelGirdleMinLines = null; public static Tuple<Vector3, Vector3> MainModelGirdleMinLines = null;
public static Tuple<Vector3, Vector3> MainModelGirdleAvgLines = null; public static Tuple<Vector3, Vector3> MainModelGirdleAvgLines = null;
/// <summary> /// <summary>
/// 模型光照 /// 模型光照
/// </summary> /// </summary>
public static List<Light3D> MainModelLighting = new List<Light3D>(); public static List<Light3D> MainModelLighting = new List<Light3D>();
public static List<MeshGeometryModel3D> MainModelMeshes = new List<MeshGeometryModel3D>(); public static List<MeshGeometryModel3D> MainModelMeshes = new List<MeshGeometryModel3D>();
public static ColorConfigEntity ColorConfig = new ColorConfigEntity(); public static ColorConfigEntity ColorConfig = new ColorConfigEntity();
/// <summary> /// <summary>
/// 模型控件对象映射 /// 模型控件对象映射
/// </summary> /// </summary>
@ -73,7 +83,7 @@ public class ViewportManager
{ {
ClearDicModels(); ClearDicModels();
_viewport.Items.Clear(); _viewport.Items.Clear();
} }
_viewport = viewport3D; _viewport = viewport3D;
@ -83,7 +93,7 @@ public class ViewportManager
if (_viewport == null) if (_viewport == null)
throw new Exception("Viewport is not set"); throw new Exception("Viewport is not set");
return _viewport; return _viewport;
} }
#region 模型选中交互管理 #region 模型选中交互管理
//是否双击选中 //是否双击选中
@ -94,7 +104,7 @@ public class ViewportManager
public static bool DoubleClickSelectShowBorderLength = false; public static bool DoubleClickSelectShowBorderLength = false;
//选中边框夹角文字 //选中边框夹角文字
public static bool DoubleClickSelectShowBorderAngle = false; public static bool DoubleClickSelectShowBorderAngle = false;
public static bool DoubleClickSelectShowInfoText = true; public static bool DoubleClickSelectShowInfoText = true;
//选中同类面 //选中同类面
public static bool DoubleClickSelectShowPlaneType = true; public static bool DoubleClickSelectShowPlaneType = true;
@ -116,11 +126,11 @@ public class ViewportManager
ClearDicModels(); ClearDicModels();
HashSet<SelShowType> models = new HashSet<SelShowType>(); HashSet<SelShowType> models = new HashSet<SelShowType>();
models.Add(SelShowType.SelPanel); models.Add(SelShowType.SelPanel);
if(DoubleClickSelectShowBorder) models.Add(SelShowType.Border); if (DoubleClickSelectShowBorder) models.Add(SelShowType.Border);
if (DoubleClickSelectShowInfoText) models.Add(SelShowType.LengthText); if (DoubleClickSelectShowInfoText) models.Add(SelShowType.LengthText);
// if (DoubleClickSelectShowBorderAngle) models.Add(SelShowType.BorderAngle); // if (DoubleClickSelectShowBorderAngle) models.Add(SelShowType.BorderAngle);
if (DoubleClickSelectShowPlaneType) models.Add(SelShowType.IsTypePanel); if (DoubleClickSelectShowPlaneType) models.Add(SelShowType.IsTypePanel);
ChooseAddModels.AddRange( ViewportHelperPro.GentrateChosenView(ChooseTriangleCode,valType, models.ToArray())); ChooseAddModels.AddRange(ViewportHelperPro.GentrateChosenView(ChooseTriangleCode, valType, models.ToArray()));
ChooseAddModels.ForEach(e => _viewport.Items.Add(e)); ChooseAddModels.ForEach(e => _viewport.Items.Add(e));
} }
/// <summary> /// <summary>
@ -153,12 +163,12 @@ public class ViewportManager
ClearDicModels(); ClearDicModels();
return; return;
} }
List<Viewport3DTriangleEntity> entities = ViewportHelperPro.GenerateLineTextModelsByType(planeType); List<Viewport3DTriangleEntity> entities = ViewportHelperPro.GenerateLineTextModelsByType(planeType);
if (entities.Count <= 0) if (entities.Count <= 0)
{ {
ClearDicModels(); ClearDicModels();
} }
ChooseTriangleCode = entities[0].TriangleCode; ChooseTriangleCode = entities[0].TriangleCode;
ResetChooseAddModels(planTypeStr); ResetChooseAddModels(planTypeStr);
} }
@ -191,17 +201,17 @@ public class ViewportManager
{"COC", PlaneType.Culet}, {"COC", PlaneType.Culet},
{"TWIST", PlaneType.UpperMainFacet}, {"TWIST", PlaneType.UpperMainFacet},
{"CULET_TO_TABLE", PlaneType.Culet}, {"CULET_TO_TABLE", PlaneType.Culet},
{"DIAMETER", PlaneType.Girdle}, {"DIAMETER", PlaneType.Girdle},
{"GIRDLE_BEZEL", PlaneType.Girdle}, {"GIRDLE_BEZEL", PlaneType.Girdle},
{"GIRDLE_BONE", PlaneType.Girdle}, {"GIRDLE_BONE", PlaneType.Girdle},
{"GIRDLE_VALLEY", PlaneType.Girdle}, {"GIRDLE_VALLEY", PlaneType.Girdle},
}; };
#endregion #endregion
#endregion #endregion
#region 统一控制方法 #region 统一控制方法
public static MeshGeometryModel3D PointTowardsTheFrontModel = new MeshGeometryModel3D(); public static MeshGeometryModel3D PointTowardsTheFrontModel = new MeshGeometryModel3D();
@ -210,7 +220,7 @@ public class ViewportManager
if (isPoint) if (isPoint)
{ {
var camera = ViewportHelperPro.CalculateCamera(PositiveDirection, ModelBounds); var camera = ViewportHelperPro.CalculateCamera(PositiveDirection, ModelBounds);
PointTowardsTheFrontModel = ViewportHelperPro.CreateArrow(camera.Position.ToVector3(), ModelBounds.Center, ModelBounds); PointTowardsTheFrontModel = ViewportHelperPro.CreateArrow(camera.Position.ToVector3(), ModelBounds.Center, ModelBounds);
_viewport.Items.Add(PointTowardsTheFrontModel); _viewport.Items.Add(PointTowardsTheFrontModel);
} }
else else
@ -244,27 +254,31 @@ public class ViewportManager
{ {
entities.AddRange(ViewportTriangle); entities.AddRange(ViewportTriangle);
} }
//重置 //重置
_viewport.Items.Clear(); _viewport.Items.Clear();
ChooseTriangleCode = string.Empty; ChooseTriangleCode = string.Empty;
ChooseAddModels.Clear(); ChooseAddModels.Clear();
ResetChooseAddModels(); ResetChooseAddModels();
//刷新三角形 //刷新三角形
ViewportTriangle.Clear(); ViewportTriangle.Clear();
ViewportTriangle.AddRange(entities); ViewportTriangle.AddRange(entities);
//初始化 //初始化
MainModel3D = ViewportHelperPro.GenerateModelByEntity(_viewport, entities); MainModel3D = ViewportHelperPro.GenerateModelByEntity(_viewport, entities);
MainModelLines = ViewportHelperPro.GentrateLineByEntity(_viewport, entities); MainModelLines = ViewportHelperPro.GentrateLineByEntity(_viewport, entities);
MainModelLighting = ViewportHelperPro.GenerateLightingForModel(_viewport); MainModelLighting = ViewportHelperPro.GenerateLightingForModel(_viewport);
MainModelMeshes = ViewportHelperPro.GenerateModelByEntityGroupByType(entities); MainModelMeshes = ViewportHelperPro.GenerateModelByEntityGroupByType(entities);
MainModelLines.AddRange(ViewportHelperPro.GentrateLineGirdleByEntity(entities)); MainModelLines.AddRange(ViewportHelperPro.GentrateLineGirdleByEntity(entities));
//切换相机视角 //切换相机视角
_viewport.Camera = ViewportHelperPro.CalculateCamera(PositiveDirection, ModelBounds); _viewport.Camera = ViewportHelperPro.CalculateCamera(PositiveDirection, ModelBounds);
_viewport.Camera.UpDirection = new Vector3D(0, -1, 0); _viewport.Camera.UpDirection = new Vector3D(0, -1, 0);
_viewport.RenderHost.MSAA = MSAALevel.Maximum; _viewport.RenderHost.MSAA = MSAALevel.Maximum;
// TODO:
MainModelMeshLines.AddRange(ViewportHelperPro.ShowMeshLines(entities));
MainModelCircleLine = ViewportHelperPro.ShowCircleLine();
} }
/// <summary> /// <summary>
@ -277,7 +291,7 @@ public class ViewportManager
if (_viewport == null) return; if (_viewport == null) return;
if (isShow) if (isShow)
{ {
if(_viewport.Items.Contains(MainModel3D)) if (_viewport.Items.Contains(MainModel3D))
return; return;
else else
_viewport.Items.Add(MainModel3D); _viewport.Items.Add(MainModel3D);
@ -287,7 +301,7 @@ public class ViewportManager
_viewport.Items.Remove(MainModel3D); _viewport.Items.Remove(MainModel3D);
} }
} }
/// <summary> /// <summary>
/// 是否显示主体模型 /// 是否显示主体模型
/// </summary> /// </summary>
@ -300,7 +314,7 @@ public class ViewportManager
{ {
MainModelMeshes.ForEach(e => MainModelMeshes.ForEach(e =>
{ {
if(!_viewport.Items.Contains(e)) if (!_viewport.Items.Contains(e))
_viewport.Items.Add(e); _viewport.Items.Add(e);
}); });
} }
@ -308,11 +322,11 @@ public class ViewportManager
{ {
MainModelMeshes.ForEach(e => MainModelMeshes.ForEach(e =>
{ {
_viewport.Items.Remove(e); _viewport.Items.Remove(e);
}); });
} }
} }
public static void ShowMainModelLines(bool isShow) public static void ShowMainModelLines(bool isShow)
{ {
@ -321,7 +335,7 @@ public class ViewportManager
{ {
MainModelLines.ForEach(e => MainModelLines.ForEach(e =>
{ {
if(!_viewport.Items.Contains(e)) if (!_viewport.Items.Contains(e))
_viewport.Items.Add(e); _viewport.Items.Add(e);
}); });
} }
@ -338,7 +352,7 @@ public class ViewportManager
{ {
MainModelLighting.ForEach(e => MainModelLighting.ForEach(e =>
{ {
if(!_viewport.Items.Contains(e)) if (!_viewport.Items.Contains(e))
_viewport.Items.Add(e); _viewport.Items.Add(e);
}); });
} }
@ -359,16 +373,16 @@ public class ViewportManager
MainModel3D.Material = _material; MainModel3D.Material = _material;
} }
} }
public static void TranslucentTex(bool isShow) public static void TranslucentTex(bool isShow)
{ {
if (_viewport == null) return; if (_viewport == null) return;
if (isShow) if (isShow)
{ {
string texturePath2 = "pack://Appliction:,,,/Res/morning_racing_circuit_16k.dds"; string texturePath2 = "pack://Appliction:,,,/Res/morning_racing_circuit_16k.dds";
var texture2 = TextureModel.Create(texturePath2); var texture2 = TextureModel.Create(texturePath2);
var material = new PBRMaterial var material = new PBRMaterial
{ {
AlbedoColor = new SharpDX.Color4(0.0f, 1.0f, 1.0f, 1.0f), // 白色基色 AlbedoColor = new SharpDX.Color4(0.0f, 1.0f, 1.0f, 1.0f), // 白色基色
@ -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 #endregion

Loading…
Cancel
Save