|
|
|
@ -10,8 +10,10 @@ using System.Windows.Media.Imaging; |
|
|
|
|
using System.Windows.Media.Media3D; |
|
|
|
|
using System.Windows.Threading; |
|
|
|
|
using HelixToolkit.Wpf.SharpDX; |
|
|
|
|
using NPOI.OpenXmlFormats.Vml.Office; |
|
|
|
|
using SharpDX; |
|
|
|
|
using SharpDX.Direct3D11; |
|
|
|
|
using SharpDX.DXGI; |
|
|
|
|
using SparkClient.Views.UserControl.ViewportData.Enum; |
|
|
|
|
using SparkClient.Views.UserControl.ViewportData.Entity; |
|
|
|
|
using Color = SharpDX.Color; |
|
|
|
@ -30,7 +32,7 @@ public class ViewportHelperPro |
|
|
|
|
public static MeshGeometryModel3D GenerateTypePanelHot(PlaneType planeType, Color4? color = null) |
|
|
|
|
{ |
|
|
|
|
var entities = ViewportManager.ViewportTriangle.Where(e=>e.PlaneType==planeType).ToList(); |
|
|
|
|
return GenerateModelByEntity(entities, color??ViewportManager.Red); |
|
|
|
|
return GenerateModelByEntity(entities, color??ViewportManager.ColorConfig.ErrFacetColor); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
#region 已经确定和调整好的方法 |
|
|
|
@ -71,8 +73,8 @@ public class ViewportHelperPro |
|
|
|
|
|
|
|
|
|
var material = new PBRMaterial |
|
|
|
|
{ |
|
|
|
|
AlbedoColor = ViewportManager.Black, // 黑色,避免其他光照影响 |
|
|
|
|
EmissiveColor =color ?? ViewportManager.LightGray , // LightGray #D3D3D3 |
|
|
|
|
AlbedoColor = new Color4(0.0f, 0f,0f,1f), // 黑色,避免其他光照影响 |
|
|
|
|
EmissiveColor =color ?? ViewportManager.ColorConfig.MainFacetColor , // LightGray #D3D3D3 |
|
|
|
|
MetallicFactor = 0.0, // 非金属 |
|
|
|
|
RoughnessFactor = 1.0, // 高粗糙度,避免反射效果 |
|
|
|
|
ReflectanceFactor = 0.0, // 无反射 |
|
|
|
@ -309,6 +311,51 @@ public class ViewportHelperPro |
|
|
|
|
return result; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
/// <summary> |
|
|
|
|
/// 通过三角形实体集合生成每个面的边框线(只生成不添加) |
|
|
|
|
/// </summary> |
|
|
|
|
/// <param name="entities"></param> |
|
|
|
|
/// <param name="color"></param> |
|
|
|
|
/// <param name="thickness"></param> |
|
|
|
|
/// <returns></returns> |
|
|
|
|
public static List<LineGeometryModel3D> GentrateLineGirdleByEntity(List<Viewport3DTriangleEntity> entities, |
|
|
|
|
Color4? color = null, double thickness = 1.0) |
|
|
|
|
{ |
|
|
|
|
List<LineGeometryModel3D> result = new List<LineGeometryModel3D>(); |
|
|
|
|
//按面分组,腰面特殊单独生成 |
|
|
|
|
List<Viewport3DTriangleEntity> waistList = entities |
|
|
|
|
.Where(entity => entity.PlaneType == PlaneType.Girdle) |
|
|
|
|
.ToList(); |
|
|
|
|
List<Vector3> selFaceVector = new List<Vector3>(); |
|
|
|
|
List<Tuple<Vector3, Vector3>> lines = new List<Tuple<Vector3, Vector3>>(); |
|
|
|
|
if (waistList.Count > 0) |
|
|
|
|
{ |
|
|
|
|
foreach (var entity in waistList) |
|
|
|
|
{ |
|
|
|
|
selFaceVector.Add(entity.Point1); |
|
|
|
|
selFaceVector.Add(entity.Point2); |
|
|
|
|
selFaceVector.Add(entity.Point3); |
|
|
|
|
} |
|
|
|
|
HashSet<Vector3> uniqueVectors = new HashSet<Vector3>(selFaceVector); |
|
|
|
|
|
|
|
|
|
for (int i = 0; i < uniqueVectors.ToList().Count - 1; i++) |
|
|
|
|
{ |
|
|
|
|
var nowItem = uniqueVectors.ToList()[i]; |
|
|
|
|
var nextItem = uniqueVectors.ToList()[i + 1]; |
|
|
|
|
var line = new Tuple<Vector3, Vector3>(nowItem, nextItem); |
|
|
|
|
if (IsLineSegmentParallelToYAxis(line)) |
|
|
|
|
{ |
|
|
|
|
lines.Add(line); |
|
|
|
|
result.Add(DisplayLineModel3D(new List<Vector3>(){nowItem,nextItem }, color??ViewportManager.ColorConfig.MainBorderColor, thickness)); |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
CalculateLineSegmentStats(lines, out ViewportManager.MainModelGirdleMaxLines, out ViewportManager.MainModelGirdleMinLines, out ViewportManager.MainModelGirdleAvgLines); |
|
|
|
|
ViewportManager.MainModelGirdleLines = lines; |
|
|
|
|
return result; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
/// <summary> |
|
|
|
|
/// 通过三角形实体集合生成每个面的边框线(只生成不添加) |
|
|
|
|
/// </summary> |
|
|
|
@ -339,7 +386,7 @@ public class ViewportHelperPro |
|
|
|
|
temp.Add(entity.Point2); |
|
|
|
|
temp.Add(entity.Point3); |
|
|
|
|
} |
|
|
|
|
result.Add(DisplayLineModel3D(VectorClockwiseSort(new HashSet<Vector3>(temp).ToList()), color??ViewportManager.LineColor, thickness)); |
|
|
|
|
result.Add(DisplayLineModel3D(VectorClockwiseSort(new HashSet<Vector3>(temp).ToList()), color??ViewportManager.ColorConfig.MainBorderColor, thickness)); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
//腰 - 特殊 |
|
|
|
@ -366,20 +413,9 @@ public class ViewportHelperPro |
|
|
|
|
else |
|
|
|
|
ViewportManager.GirdleTopLines.Add(vector); |
|
|
|
|
} |
|
|
|
|
result.Add(DisplayLineModel3D( VectorClockwiseSort(ViewportManager.GirdleBottomLines), color??ViewportManager.LineColor, thickness)); |
|
|
|
|
result.Add(DisplayLineModel3D( VectorClockwiseSort(ViewportManager.GirdleTopLines), color??ViewportManager.LineColor, thickness)); |
|
|
|
|
//找到所有平行于Y轴的线 |
|
|
|
|
for (int i = 0; i < uniqueVectors.ToList().Count - 1; i++) |
|
|
|
|
{ |
|
|
|
|
var nowItem = uniqueVectors.ToList()[i]; |
|
|
|
|
var nextItem = uniqueVectors.ToList()[i + 1]; |
|
|
|
|
var line = new Tuple<Vector3, Vector3>(nowItem, nextItem); |
|
|
|
|
if (IsLineSegmentParallelToYAxis(line)) |
|
|
|
|
{ |
|
|
|
|
result.Add(DisplayLineModel3D(new List<Vector3>(){nowItem,nextItem }, color??ViewportManager.LineColor, thickness)); |
|
|
|
|
} |
|
|
|
|
result.Add(DisplayLineModel3D( VectorClockwiseSort(ViewportManager.GirdleBottomLines), color??ViewportManager.ColorConfig.MainBorderColor, thickness)); |
|
|
|
|
result.Add(DisplayLineModel3D( VectorClockwiseSort(ViewportManager.GirdleTopLines), color??ViewportManager.ColorConfig.MainBorderColor, thickness)); |
|
|
|
|
|
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
return result; |
|
|
|
@ -396,30 +432,48 @@ public class ViewportHelperPro |
|
|
|
|
Color4? textColor = null,bool showAll = false) |
|
|
|
|
{ |
|
|
|
|
var result = new List<GeometryModel3D>(); |
|
|
|
|
var selFaceVector = entities |
|
|
|
|
.SelectMany(entity => new[] { entity.Point1, entity.Point2, entity.Point3 }) |
|
|
|
|
.Distinct() |
|
|
|
|
.ToList(); |
|
|
|
|
var uniqueLines = new HashSet<string>(); |
|
|
|
|
var sortedVectors = VectorClockwiseSort(selFaceVector); |
|
|
|
|
for (int i = 0; i < sortedVectors.Count; i++) |
|
|
|
|
if (entities.Count > 0 && entities[0].PlaneType == PlaneType.Girdle) |
|
|
|
|
{ |
|
|
|
|
var current = sortedVectors[i]; |
|
|
|
|
var next = sortedVectors[(i + 1) % sortedVectors.Count]; |
|
|
|
|
|
|
|
|
|
double length = (next - current).Length(); |
|
|
|
|
string lineKey = $"{length:F2}"; |
|
|
|
|
if (showAll == false) |
|
|
|
|
if (ViewportManager.MainModelGirdleMaxLines != null || ViewportManager.MainModelGirdleMinLines != null || |
|
|
|
|
ViewportManager.MainModelGirdleAvgLines != null) |
|
|
|
|
{ |
|
|
|
|
if (uniqueLines.Contains(lineKey)) continue; |
|
|
|
|
uniqueLines.Add(lineKey); |
|
|
|
|
result.Add(DisplayLineModel3D(new List<Tuple<Vector3,Vector3>>(){ViewportManager.MainModelGirdleMaxLines}, new Color4(1f, 0, 0, 1f) )); |
|
|
|
|
result.Add(DisplayLineModel3D(new List<Tuple<Vector3,Vector3>>(){ViewportManager.MainModelGirdleMinLines}, new Color4(0f, 1f, 0, 1f) )); |
|
|
|
|
result.Add(DisplayLineModel3D(new List<Tuple<Vector3,Vector3>>(){ViewportManager.MainModelGirdleAvgLines}, new Color4(1f, 0.5f, 0, 1f) )); |
|
|
|
|
result.Add(DisplayText3D($"{CalculateLength(ViewportManager.MainModelGirdleMaxLines)}mm", ViewportManager.MainModelGirdleMaxLines.Item1, textColor)); |
|
|
|
|
result.Add(DisplayText3D($"{CalculateLength(ViewportManager.MainModelGirdleMinLines)}mm", ViewportManager.MainModelGirdleMinLines.Item1, textColor)); |
|
|
|
|
result.Add(DisplayText3D($"{CalculateLength(ViewportManager.MainModelGirdleAvgLines)}mm", ViewportManager.MainModelGirdleAvgLines.Item1, textColor)); |
|
|
|
|
} |
|
|
|
|
var midPoint = (current + next) / 2; |
|
|
|
|
var text = $"{length:F2}mm"; |
|
|
|
|
var textY = midPoint.Y > ViewportManager.CenterVector.Y ? midPoint.Y + 0.3f : midPoint.Y - 0.3f; |
|
|
|
|
var lengthTextModel = DisplayText3D(text, new Vector3(midPoint.X, textY, midPoint.Z),next - current, textColor); |
|
|
|
|
result.Add(lengthTextModel); |
|
|
|
|
} |
|
|
|
|
else |
|
|
|
|
{ |
|
|
|
|
var selFaceVector = entities |
|
|
|
|
.SelectMany(entity => new[] { entity.Point1, entity.Point2, entity.Point3 }) |
|
|
|
|
.Distinct() |
|
|
|
|
.ToList(); |
|
|
|
|
var uniqueLines = new HashSet<string>(); |
|
|
|
|
var sortedVectors = VectorClockwiseSort(selFaceVector); |
|
|
|
|
for (int i = 0; i < sortedVectors.Count; i++) |
|
|
|
|
{ |
|
|
|
|
var current = sortedVectors[i]; |
|
|
|
|
var next = sortedVectors[(i + 1) % sortedVectors.Count]; |
|
|
|
|
|
|
|
|
|
double length = (next - current).Length(); |
|
|
|
|
string lineKey = $"{length:F2}"; |
|
|
|
|
if (showAll == false) |
|
|
|
|
{ |
|
|
|
|
if (uniqueLines.Contains(lineKey)) continue; |
|
|
|
|
uniqueLines.Add(lineKey); |
|
|
|
|
} |
|
|
|
|
var midPoint = (current + next) / 2; |
|
|
|
|
var text = $"{length:F2}mm"; |
|
|
|
|
var textY = midPoint.Y > ViewportManager.CenterVector.Y ? midPoint.Y + 0.3f : midPoint.Y - 0.3f; |
|
|
|
|
var lengthTextModel = DisplayText3D(text, new Vector3(midPoint.X, textY, midPoint.Z),next - current, textColor); |
|
|
|
|
result.Add(lengthTextModel); |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
return result; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
@ -468,19 +522,19 @@ public class ViewportHelperPro |
|
|
|
|
{ |
|
|
|
|
case SelShowType.SelPanel: |
|
|
|
|
//选中面的高亮 |
|
|
|
|
result.Add(GenerateModelByEntity(selPanel, ViewportManager.DarkKhaki)); |
|
|
|
|
result.Add(GenerateModelByEntity(selPanel, ViewportManager.ColorConfig.SelFacetColor)); |
|
|
|
|
break; |
|
|
|
|
case SelShowType.Border: |
|
|
|
|
//选中面边框的高亮 |
|
|
|
|
result.AddRange(GentrateLineByEntity(selPanel, ViewportManager.Black)); |
|
|
|
|
result.AddRange(GentrateLineByEntity(selPanel, ViewportManager.ColorConfig.SelFacetColor)); |
|
|
|
|
break; |
|
|
|
|
case SelShowType.IsTypePanel: |
|
|
|
|
//选中面的同类面高亮 |
|
|
|
|
result.Add(GenerateModelByEntity(selPanelType, ViewportManager.LtGoldenrodYello)); |
|
|
|
|
result.Add(GenerateModelByEntity(selPanelType, ViewportManager.ColorConfig.SelTypeColor)); |
|
|
|
|
break; |
|
|
|
|
case SelShowType.LengthText: |
|
|
|
|
//选中面 每条边长度标记 |
|
|
|
|
if(PlaneType.Girdle == entity.PlaneType)break; |
|
|
|
|
// if(PlaneType.Girdle == entity.PlaneType)break; |
|
|
|
|
result.AddRange(GenerateLineTextModels(selPanel)); |
|
|
|
|
break; |
|
|
|
|
case SelShowType.BorderAngle: |
|
|
|
@ -596,8 +650,9 @@ public class ViewportHelperPro |
|
|
|
|
var billboardText = new BillboardText3D(); |
|
|
|
|
billboardText.TextInfo.Add(new TextInfo(text, position) |
|
|
|
|
{ |
|
|
|
|
Foreground = color??ViewportManager.Red, |
|
|
|
|
Scale = 0.5f, |
|
|
|
|
Foreground = color??ViewportManager.ColorConfig.SelFontColor, |
|
|
|
|
Scale = 0.8f, |
|
|
|
|
|
|
|
|
|
}); |
|
|
|
|
billboardTextModel.Geometry = billboardText; |
|
|
|
|
return billboardTextModel; |
|
|
|
@ -622,7 +677,7 @@ public class ViewportHelperPro |
|
|
|
|
TextInfo = new ObservableCollection<TextInfo>() |
|
|
|
|
{ |
|
|
|
|
new TextInfo(text, position){ |
|
|
|
|
Foreground = color ?? ViewportManager.Red, |
|
|
|
|
Foreground = color ?? ViewportManager.ColorConfig.SelFontColor, |
|
|
|
|
Scale = 0.5f, |
|
|
|
|
Offset = new Vector2(0.2f, 0.2f), |
|
|
|
|
// Angle = (float)angle // 设置文字的旋转角度 |
|
|
|
@ -1033,6 +1088,30 @@ public class ViewportHelperPro |
|
|
|
|
} |
|
|
|
|
return false; // 不平行于 Y 轴 |
|
|
|
|
} |
|
|
|
|
private static void CalculateLineSegmentStats(List<Tuple<Vector3, Vector3>> lines, |
|
|
|
|
out Tuple<Vector3, Vector3> maxLine, |
|
|
|
|
out Tuple<Vector3, Vector3> minLine, |
|
|
|
|
out Tuple<Vector3, Vector3> avgLine) |
|
|
|
|
{ |
|
|
|
|
// 计算所有线段的长度 |
|
|
|
|
var lineLengths = lines.Select(line => new |
|
|
|
|
{ |
|
|
|
|
Line = line, |
|
|
|
|
Length = CalculateLength(line) |
|
|
|
|
}).ToList(); |
|
|
|
|
|
|
|
|
|
// 找到最大、最小和平均长度对应的线段 |
|
|
|
|
maxLine = lineLengths.OrderByDescending(l => l.Length).First().Line; |
|
|
|
|
minLine = lineLengths.OrderBy(l => l.Length).First().Line; |
|
|
|
|
avgLine = lineLengths.OrderBy(l => Math.Abs(l.Length - lineLengths.Average(ll => ll.Length))) |
|
|
|
|
.First().Line; |
|
|
|
|
} |
|
|
|
|
private static float CalculateLength(Tuple<Vector3, Vector3> line) |
|
|
|
|
{ |
|
|
|
|
Vector3 startPoint = line.Item1; |
|
|
|
|
Vector3 endPoint = line.Item2; |
|
|
|
|
return Vector3.Distance(startPoint, endPoint); |
|
|
|
|
} |
|
|
|
|
#endregion |
|
|
|
|
|
|
|
|
|
} |