From 2e183ad96e257bd6fff67b14a7926a15a3527f72 Mon Sep 17 00:00:00 2001 From: Tongg Date: Tue, 11 Mar 2025 17:15:58 +0800 Subject: [PATCH] fix: 20250311 --- App.config | 1 + Language/zh_CN.xaml | 1 + LoginWindow.xaml | 7 +- LoginWindow.xaml.cs | 1 + Views/UserControl/Viewport3D.xaml | 5 +- Views/UserControl/Viewport3D.xaml.cs | 14 + .../ViewportData/Helper/ViewportHelperPro.cs | 335 +++++++++++++----- .../ViewportData/Helper/ViewportManager.cs | 15 + 8 files changed, 295 insertions(+), 84 deletions(-) diff --git a/App.config b/App.config index 4ba9578..9cb7d5e 100644 --- a/App.config +++ b/App.config @@ -16,6 +16,7 @@ + diff --git a/Language/zh_CN.xaml b/Language/zh_CN.xaml index 54fb6a7..37dc1e1 100644 --- a/Language/zh_CN.xaml +++ b/Language/zh_CN.xaml @@ -156,6 +156,7 @@ 选择路径 重置网格线 切工仪旋转至此面 + 显示中心标记 星辉钻石检测系统 diff --git a/LoginWindow.xaml b/LoginWindow.xaml index ba7cdd6..20d6c35 100644 --- a/LoginWindow.xaml +++ b/LoginWindow.xaml @@ -10,7 +10,7 @@ AllowsTransparency="True" Background="Transparent" ResizeMode="NoResize" - Title="LoginWindow" Height="450" Width="450" + Title="LoginWindow" Height="460" Width="450" KeyDown="PasswordBox_KeyDown"> + @@ -140,8 +141,10 @@ - + diff --git a/LoginWindow.xaml.cs b/LoginWindow.xaml.cs index aaa95c0..beb09fc 100644 --- a/LoginWindow.xaml.cs +++ b/LoginWindow.xaml.cs @@ -19,6 +19,7 @@ public partial class LoginWindow : Window WindowStartupLocation = WindowStartupLocation.CenterScreen; AccountTextBox.Text = Settings.SelectValueById("SAVE_ACCOUNT"); PasswordBox.Password = Settings.SelectValueById("SAVE_PASSWORD"); + TBlockAppVersion.Text = $"Version {ConfigurationHelper.ReadConfigValue("AppVersion")}"; //checkCUDA(); checkNvidia(); // 检测MSVCRuntime是否安装 diff --git a/Views/UserControl/Viewport3D.xaml b/Views/UserControl/Viewport3D.xaml index 611bf10..7e5db06 100644 --- a/Views/UserControl/Viewport3D.xaml +++ b/Views/UserControl/Viewport3D.xaml @@ -64,6 +64,7 @@ + @@ -82,7 +83,9 @@ PreviewMouseRightButtonUp="UIElement_OnPreviewMouseRightButtonUp" PreviewMouseRightButtonDown="UIElement_OnPreviewMouseRightButtonDown" PreviewMouseMove="Viewport3Dx_OnPreviewMouseMove" - MouseDoubleClick="Viewport3Dx_OnMouseLeftButtonDown"> + + MouseDown="Viewport3Dx_OnMouseLeftButtonDown"> + diff --git a/Views/UserControl/Viewport3D.xaml.cs b/Views/UserControl/Viewport3D.xaml.cs index 86b1d02..c443a21 100644 --- a/Views/UserControl/Viewport3D.xaml.cs +++ b/Views/UserControl/Viewport3D.xaml.cs @@ -451,6 +451,19 @@ public partial class Viewport3D case "ViewportRightMenuShowMeshLines": ViewportManager.ShowMeshLines(checkResult, ViewportHelperPro.IsCrown()); break; + case "ViewportCenterFlag": + //显示模型中心标定 + if (checkResult) + { + ViewportManager.ShowMainModel3D(false); + ViewportManager.ShowMainModel3DByType(false); + } + ViewportManager.ShowCenterFlag(checkResult); + if (checkResult) + { + ViewportManager.ShowMainModel3D(true); + } + break; } } /// @@ -633,4 +646,5 @@ public partial class Viewport3D //Viewport3Dx.ShowTriangleCountInfo = !Viewport3Dx.ShowTriangleCountInfo; } + } \ No newline at end of file diff --git a/Views/UserControl/ViewportData/Helper/ViewportHelperPro.cs b/Views/UserControl/ViewportData/Helper/ViewportHelperPro.cs index b614d76..512d369 100644 --- a/Views/UserControl/ViewportData/Helper/ViewportHelperPro.cs +++ b/Views/UserControl/ViewportData/Helper/ViewportHelperPro.cs @@ -75,11 +75,11 @@ public class ViewportHelperPro } } var mesh = meshBuilder.ToMeshGeometry3D(); - + color = new Color4(color ?? ViewportManager.ColorConfig.MainFacetColor); var material = new PBRMaterial { - AlbedoColor = new Color4(0.0f, 0f,0f,0.8f), // 黑色,避免其他光照影响 - EmissiveColor =color ?? ViewportManager.ColorConfig.MainFacetColor , // LightGray #D3D3D3 + AlbedoColor = new Color4(0.0f, 0f,0f,0.7f), // 黑色,避免其他光照影响 + EmissiveColor =new Color4(color.Value.Red, color.Value.Green, color.Value.Blue, 0.7f) , // LightGray #D3D3D3 MetallicFactor = 0.0, // 非金属 RoughnessFactor = 1.0, // 高粗糙度,避免反射效果 ReflectanceFactor = 0.0, // 无反射 @@ -123,6 +123,8 @@ public class ViewportHelperPro return result; } + + private static Color4? GenFaceColor4(PlaneType planeType) { switch (planeType) @@ -304,6 +306,73 @@ public class ViewportHelperPro }).ConfigureAwait(false); } + + public static List ShowCenterTag(float lineLength = 0.5f) + { + List result = new List(); + + Vector3 boxCenter = ViewportManager.CenterVector; + //中心 22 + Tuple centerLineX = new Tuple( + new Vector3(boxCenter.X - lineLength, boxCenter.Y, boxCenter.Z), + new Vector3(boxCenter.X + lineLength, boxCenter.Y, boxCenter.Z)); + Tuple centerLineZ = new Tuple( + new Vector3(boxCenter.X, boxCenter.Y, boxCenter.Z - lineLength), + new Vector3(boxCenter.X, boxCenter.Y, boxCenter.Z + lineLength)); + //中心 台 + List tablePoints = new List(); + foreach (var entity in ViewportManager.ViewportTriangle.Where(entity => entity.PlaneType == PlaneType.TableFacet).ToList()) + { + tablePoints.Add(entity.Point1); + tablePoints.Add(entity.Point2); + tablePoints.Add(entity.Point3); + } + HashSet tablePointSet = new HashSet(tablePoints); + tablePoints = VectorClockwiseSort(tablePointSet.ToList()); + + List> line = new List>(); + for (int i = 0; i < tablePoints.Count / 2; i++) + { + line.Add(new Tuple(tablePoints[i], tablePoints[i+tablePoints.Count / 2])); + } + + + Vector3 tableCenter = CalculateIntersection(line.Last(), line.First()) ?? GetCentroid(tablePointSet.ToList()); + Tuple tableLineX = new Tuple( + new Vector3(tableCenter.X - lineLength, tableCenter.Y, tableCenter.Z), + new Vector3(tableCenter.X + lineLength, tableCenter.Y, tableCenter.Z)); + Tuple tableLineZ = new Tuple( + new Vector3(tableCenter.X, tableCenter.Y, tableCenter.Z - lineLength), + new Vector3(tableCenter.X, tableCenter.Y, tableCenter.Z + lineLength)); + //中心 底尖 + List culetPoints = new List(); + foreach (var entity in ViewportManager.ViewportTriangle.Where(entity => entity.PlaneType == PlaneType.Culet).ToList()) + { + culetPoints.Add(entity.Point1); + culetPoints.Add(entity.Point2); + culetPoints.Add(entity.Point3); + } + Vector3 culetCenter = GetCentroid(culetPoints); + Tuple culetLineX = new Tuple( + new Vector3(culetCenter.X - lineLength, culetCenter.Y, culetCenter.Z), + new Vector3(culetCenter.X + lineLength, culetCenter.Y, culetCenter.Z)); + Tuple culetLineZ = new Tuple( + new Vector3(culetCenter.X, culetCenter.Y, culetCenter.Z - lineLength), + new Vector3(culetCenter.X, culetCenter.Y, culetCenter.Z + lineLength)); + + List> centerLines = new List> + { centerLineX, centerLineZ}; + List> tableLines = new List> + { tableLineX, tableLineZ }; + List> culetLines = new List> + { culetLineZ, culetLineX }; + + result.Add(DisplayLineModel3D(centerLines, Color.Red, 0.8f)); + result.Add(DisplayLineModel3D(tableLines, Color.Green, 1f)); + result.Add(DisplayLineModel3D(culetLines, Color.Blue, 0.8f)); + return result; + } + /// /// 通过三角形实体集合生成每个面的边框线 /// @@ -316,6 +385,7 @@ public class ViewportHelperPro return result; } + /// /// 通过三角形实体集合生成每个面的边框线(只生成不添加) /// @@ -520,91 +590,153 @@ public class ViewportHelperPro var result = new List(); if (selFacetType == PlaneType.Girdle && string.IsNullOrWhiteSpace(valKey)) { - Logger.Info($"【面文本生成】 命中面{selFacetType},是腰"); + // Logger.Info($"【面文本生成】 命中面{selFacetType},是腰"); + // List facetTypeAll = + // ViewportManager.ViewportTriangle.FindAll(e => e.PlaneType == selFacetType); + // var groupedDic = facetTypeAll.GroupBy(entity => entity.PlaneCode) + // .ToDictionary(group => group.Key, group => group.ToList()); + // Logger.Info($"【面文本生成】 腰由{groupedDic.Count}个面组成"); + // + // var selPlaneCode = entities.First().PlaneCode; + // Logger.Info($"【面文本生成】 当前选择{selPlaneCode}"); + // + // List facetPoints = new List(); + // entities.ForEach(e => { facetPoints.Add(e.Point1); facetPoints.Add(e.Point2); facetPoints.Add(e.Point3); }); + // var facetIndex = -1; + // int.TryParse(selPlaneCode.Split("_")[1], out facetIndex); + // + // if (facetIndex == -1) + // { + // Logger.Info($"【面文本生成】 面索引解析失败{selPlaneCode}"); + // return result; + // } + // int linePointType = facetIndex % 4; + // Console.WriteLine(facetIndex); + // switch (linePointType) + // { + // case 0: + // case 2: + // var longestLine1 = GetLeftOrRightLineSegment(facetPoints, facetIndex >= 25 && facetIndex <= 57 ? true : false); + // result.Add(DisplayLineModel3D(new List>() { longestLine1 }, new Color4(1f, 0, 0, 1f), 2f)); + // break; + // case 1: + // case 3: + // var longestLine2 = GetLeftOrRightLineSegment(facetPoints, facetIndex >= 25 && facetIndex <= 57 ? false : true); + // result.Add(DisplayLineModel3D(new List>() { longestLine2 }, new Color4(1f, 0, 0, 1f), 2f)); + // break; + // } + // + // if (result.Exists(e => e == null)) + // { + // Logger.Info("目标线段为空"); + // return result; + // } + + //开始找值[选中线的值] + // string param = string.Empty; + // var valueIndex = 0; + // if (facetIndex % 8 == 0 || (facetIndex + 1) % 8 == 0) + // { + // //上腰面 + // Logger.Info($"【面文本生成】 腰面值 波峰【上腰面】"); + // valueIndex = (int)Math.Ceiling(facetIndex / 8.0) == 8 ? 0 : (int)Math.Ceiling(facetIndex / 8.0); + // param = "GIRDLE_BONE"; + // } else if (linePointType == 3 || linePointType == 0) + // { + // //风筝面 + // Logger.Info($"【面文本生成】 腰面值 波峰【风筝面】"); + // valueIndex = (facetIndex / 8); + // param = "GIRDLE_BEZEL"; + // } + // else + // { + // //腰厚比 + // Logger.Info($"【面文本生成】 腰面值 波峰【腰厚比】"); + // valueIndex = (facetIndex / 4); + // param = "GIRDLE_VALLEY"; + // } + // + // valueIndex += 1; + // var detail = ViewportManager.DiamondData[$"{param}_DETAIL"]; + // if (detail == null) + // { + // Logger.Info($"【面文本生成】 {param}_DETAIL Key不存在"); + // return result; + // } + // Logger.Info($"【面文本生成】 {param}_DETAIL == {detail}"); + // var paramValue = detail[$"{param}_{valueIndex}"]; + // if (paramValue == null) + // { + // Logger.Info($"【面文本生成】 {param}_DETAIL.{param}_{valueIndex} Key不存在"); + // return result; + // } + // Logger.Info($"【面文本生成】 {param}_DETAIL.{param}_{valueIndex} ==={paramValue}"); + // var valueFloat = (Math.Floor(float.Parse(paramValue.ToString()) * 1000) / 10).ToString(); + // Logger.Info($"【面文本生成】 {valueFloat} -- {valueIndex}"); + // var facetTextPoint = GetOffsetCenter(facetPoints, ViewportManager.CenterVector); + // result.Add(DisplayText3D($"{valueFloat}", facetTextPoint)); List facetTypeAll = ViewportManager.ViewportTriangle.FindAll(e => e.PlaneType == selFacetType); var groupedDic = facetTypeAll.GroupBy(entity => entity.PlaneCode) .ToDictionary(group => group.Key, group => group.ToList()); - Logger.Info($"【面文本生成】 腰由{groupedDic.Count}个面组成"); - - var selPlaneCode = entities.First().PlaneCode; - Logger.Info($"【面文本生成】 当前选择{selPlaneCode}"); - - List facetPoints = new List(); - entities.ForEach(e => { facetPoints.Add(e.Point1); facetPoints.Add(e.Point2); facetPoints.Add(e.Point3); }); - var facetIndex = -1; - int.TryParse(selPlaneCode.Split("_")[1], out facetIndex); - - if (facetIndex == -1) - { - Logger.Info($"【面文本生成】 面索引解析失败{selPlaneCode}"); - return result; - } - int linePointType = facetIndex % 4; - Console.WriteLine(facetIndex); - switch (linePointType) - { - case 0: - case 2: - var longestLine1 = GetLeftOrRightLineSegment(facetPoints, facetIndex >= 25 && facetIndex <= 57 ? true : false); - result.Add(DisplayLineModel3D(new List>() { longestLine1 }, new Color4(1f, 0, 0, 1f), 2f)); - break; - case 1: - case 3: - var longestLine2 = GetLeftOrRightLineSegment(facetPoints, facetIndex >= 25 && facetIndex <= 57 ? false : true); - result.Add(DisplayLineModel3D(new List>() { longestLine2 }, new Color4(1f, 0, 0, 1f), 2f)); - break; - } - - if (result.Exists(e => e == null)) - { - Logger.Info("目标线段为空"); - return result; - } - - //开始找值 - string param = string.Empty; - var valueIndex = 0; - if (facetIndex % 8 == 0 || (facetIndex + 1) % 8 == 0) - { - //上腰面 - Logger.Info($"【面文本生成】 腰面值 波峰【上腰面】"); - valueIndex = (int)Math.Ceiling(facetIndex / 8.0) == 8 ? 0 : (int)Math.Ceiling(facetIndex / 8.0); - param = "GIRDLE_BONE"; - } else if (linePointType == 3 || linePointType == 0) - { - //风筝面 - Logger.Info($"【面文本生成】 腰面值 波峰【风筝面】"); - valueIndex = (facetIndex / 8); - param = "GIRDLE_BEZEL"; - } - else + List girdleKey = new List { "GIRDLE_BEZEL", "GIRDLE_BONE", "GIRDLE_VALLEY" }; + var girdleResultDic = new Dictionary>>(); + foreach (var key in girdleKey) { - //腰厚比 - Logger.Info($"【面文本生成】 腰面值 波峰【腰厚比】"); - valueIndex = (facetIndex / 4); - param = "GIRDLE_VALLEY"; + var resultDic = new Dictionary>(); + for (int i = 0; i < groupedDic.Count; i++) + { + switch (key) + { + case "GIRDLE_BEZEL": if (i % 8 == 4) resultDic.Add($"0_{i}", groupedDic[$"0_{i}"]); + break; + case "GIRDLE_BONE": if (i % 8 == 0) resultDic.Add($"0_{i}", groupedDic[$"0_{i}"]); + break; + case "GIRDLE_VALLEY": if (i % 4 == 2) resultDic.Add($"0_{i}", groupedDic[$"0_{i}"]); + break; + } + } + girdleResultDic.Add(key, resultDic); } - valueIndex += 1; - var detail = ViewportManager.DiamondData[$"{param}_DETAIL"]; - if (detail == null) + foreach (var gridleResult in girdleResultDic) { - Logger.Info($"【面文本生成】 {param}_DETAIL Key不存在"); - return result; - } - Logger.Info($"【面文本生成】 {param}_DETAIL == {detail}"); - var paramValue = detail[$"{param}_{valueIndex}"]; - if (paramValue == null) - { - Logger.Info($"【面文本生成】 {param}_DETAIL.{param}_{valueIndex} Key不存在"); - return result; + foreach (var dic in gridleResult.Value) + { + //高亮四边形左边的线,并绑定值 + List facetPoints = new List(); + dic.Value.ForEach(e => { facetPoints.Add(e.Point1); facetPoints.Add(e.Point2); facetPoints.Add(e.Point3); }); + //高亮的线 + var facetIndex = int.Parse(dic.Key.Split("_")[1]) - 1; + if ("GIRDLE_VALLEY".Equals(gridleResult.Key)) + { + var showLine =GetLeftOrRightLineSegment(facetPoints, facetIndex >= 25 && facetIndex <= 57 ? true : false);; + if (showLine == null) continue; + result.Add(DisplayLineModel3D(new List>() { showLine }, new Color4(1f, 0, 0, 1f), 2f)); + } + //文字显示位置 + var facetTextPoint = GetOffsetCenter(facetPoints, ViewportManager.CenterVector); + var resIndex = gridleResult.Value.Keys.ToList().IndexOf(dic.Key); + if (resIndex == -1) continue; + resIndex += 1; + var detail = ViewportManager.DiamondData[$"{gridleResult.Key}_DETAIL"]; + if (detail == null) + { + Logger.Info($"【面文本生成】 {gridleResult.Key}_DETAIL Key不存在"); + return result; + } + Logger.Info($"【面文本生成】 {gridleResult.Key}_DETAIL == {detail}"); + var paramValue = detail[$"{gridleResult.Key}_{resIndex}"]; + if (paramValue == null) + { + Logger.Info($"【面文本生成】 {gridleResult.Key}_DETAIL.{gridleResult.Key}_{resIndex} Key不存在"); + return result; + } + + var valueFloat = ValueFormat(paramValue.ToString(), gridleResult.Key, false); + result.Add(DisplayText3D($"{valueFloat}", facetTextPoint)); + } } - Logger.Info($"【面文本生成】 {param}_DETAIL.{param}_{valueIndex} ==={paramValue}"); - var valueFloat = (Math.Floor(float.Parse(paramValue.ToString()) * 1000) / 10).ToString(); - Logger.Info($"【面文本生成】 {valueFloat} -- {valueIndex}"); - var facetTextPoint = GetOffsetCenter(facetPoints, ViewportManager.CenterVector); - result.Add(DisplayText3D($"{valueFloat}", facetTextPoint)); } else if (selFacetType == PlaneType.Girdle && !string.IsNullOrWhiteSpace(valKey)) { @@ -1329,7 +1461,7 @@ public class ViewportHelperPro /// /// /// - public static List ShowMeshLines(bool isCrown = true, double thickness = 0.2) + public static List ShowMeshLines(bool isCrown = true, double thickness = 0.5) { List lines = new(); var Y = -0.01F; @@ -1668,7 +1800,7 @@ public class ViewportHelperPro /// /// /// - public static LineGeometryModel3D ShowCircleLine(bool isCrown = true, double radius = 1.0, double thickness = 0.2) + public static LineGeometryModel3D ShowCircleLine(bool isCrown = true, double radius = 1.0, double thickness = 0.5) { var Y = -0.01F; if (!isCrown) @@ -2085,6 +2217,47 @@ public class ViewportHelperPro return "--"; } + private static Vector3? CalculateIntersection( + Tuple line1, + Tuple line2) + { + // 提取线段端点 + Vector3 a1 = line1.Item1, a2 = line1.Item2; + Vector3 b1 = line2.Item1, b2 = line2.Item2; + + // 投影到XZ平面(忽略Y轴) + float dx1 = a2.X - a1.X; + float dz1 = a2.Z - a1.Z; + float dx2 = b2.X - b1.X; + float dz2 = b2.Z - b1.Z; + + // 计算分母 + float denominator = dx1 * dz2 - dx2 * dz1; + + // 检查平行或共线 + if (Math.Abs(denominator) < float.Epsilon) + return null; // 无唯一交点 + + // 计算参数t和s + float t = ((b1.X - a1.X) * dz2 - (b1.Z - a1.Z) * dx2) / denominator; + float s = ((a1.X - b1.X) * dz1 - (a1.Z - b1.Z) * dx1) / -denominator; + + // 检查交点是否在线段范围内 + if (t < 0 || t > 1 || s < 0 || s > 1) + return null; // 线段不相交 + + // 计算交点坐标(XZ平面) + float x = a1.X + dx1 * t; + float z = a1.Z + dz1 * t; + + // 计算最大Y值 + float maxY = Math.Max( + Math.Max(a1.Y, a2.Y), + Math.Max(b1.Y, b2.Y) + ); + + return new Vector3(x, maxY, z); + } #endregion } diff --git a/Views/UserControl/ViewportData/Helper/ViewportManager.cs b/Views/UserControl/ViewportData/Helper/ViewportManager.cs index c9b27ba..ea12854 100644 --- a/Views/UserControl/ViewportData/Helper/ViewportManager.cs +++ b/Views/UserControl/ViewportData/Helper/ViewportManager.cs @@ -570,6 +570,21 @@ public class ViewportManager } } + public static List centerFlag = new List(); + public static void ShowCenterFlag(bool isShow) + { + if (_viewport == null) return; + if (isShow) + { + centerFlag = ViewportHelperPro.ShowCenterTag(); + centerFlag.ForEach(e => _viewport.Items.Add(e)); + } + else + { + centerFlag.ForEach(e => _viewport.Items.Remove(e)); + } + } + public static void ClearMeshLines() { ViewportManager.ShowMeshLines(false, true);