diff --git a/SparkClient.sln.DotSettings.user b/SparkClient.sln.DotSettings.user index 5cf8b2c..b08fda8 100644 --- a/SparkClient.sln.DotSettings.user +++ b/SparkClient.sln.DotSettings.user @@ -39,6 +39,7 @@ ForceIncluded ForceIncluded ForceIncluded + ForceIncluded ForceIncluded ForceIncluded ForceIncluded diff --git a/Views/UserControl/Viewport3D.xaml b/Views/UserControl/Viewport3D.xaml index 8f918b4..d1b5eb3 100644 --- a/Views/UserControl/Viewport3D.xaml +++ b/Views/UserControl/Viewport3D.xaml @@ -139,7 +139,7 @@ - + diff --git a/Views/UserControl/Viewport3D.xaml.cs b/Views/UserControl/Viewport3D.xaml.cs index f09fc84..187864c 100644 --- a/Views/UserControl/Viewport3D.xaml.cs +++ b/Views/UserControl/Viewport3D.xaml.cs @@ -202,58 +202,144 @@ public partial class Viewport3D private void BtnDirection_OnClick(object sender, RoutedEventArgs e) { var directionName = ((Button)sender).Name.ToString(); - var directionValue = (int)TbCustomizeRevolve.Value; // 旋转角度(单位:度) + var directionValue = (int)TbCustomizeRevolve.Value; - // 获取当前相机和模型中心 + if (directionValue == 0) return; + var camera = Viewport3Dx.Camera as HelixToolkit.Wpf.SharpDX.PerspectiveCamera; if (camera == null) return; - var modelCenter = ViewportManager.CenterVector; // 模型中心 + var modelCenter = ViewportManager.CenterVector; var currentPosition = camera.Position; - - // 将相机位置转换为极坐标 + var dx = currentPosition.X - modelCenter.X; var dy = currentPosition.Y - modelCenter.Y; var dz = currentPosition.Z - modelCenter.Z; - var radius = Math.Sqrt(dx * dx + dy * dy + dz * dz); // 相机与模型中心的距离 - var azimuth = Math.Atan2(dz, dx) * 180.0 / Math.PI; // 方位角(水平平面上的角度) - var elevation = Math.Atan2(dy, Math.Sqrt(dx * dx + dz * dz)) * 180.0 / Math.PI; // 仰角(垂直方向的角度) - + var radius = Math.Sqrt(dx * dx + dy * dy + dz * dz); + var azimuth = Math.Atan2(dz, dx) * 180.0 / Math.PI; + var elevation = Math.Atan2(dy, Math.Sqrt(dx * dx + dz * dz)) * 180.0 / Math.PI; + switch (directionName) { case "BtnTop": - //上 elevation += directionValue; break; case "BtnBottom": - //下 elevation -= directionValue; break; case "BtnLeft": - //左 azimuth -= directionValue; break; case "BtnRight": - //右 azimuth += directionValue; break; } - // 限制仰角范围在 -89.9 到 89.9 度,避免超出范围导致位置错误 - elevation = Math.Clamp(elevation, -89.9, 89.9); - azimuth = (azimuth + 360) % 360; // 方位角在 0 到 360 范围内循环 - - // 将极坐标转换回直角坐标 + if (elevation >= 90) + { + elevation = 89.9f; + azimuth += 180.0f; + } + else if (elevation <= -90) + { + elevation = -89.9f; + azimuth += 180.0f; + } + azimuth = (azimuth + 360) % 360; + var newX = modelCenter.X + radius * Math.Cos(elevation * Math.PI / 180.0) * Math.Cos(azimuth * Math.PI / 180.0); var newY = modelCenter.Y + radius * Math.Sin(elevation * Math.PI / 180.0); var newZ = modelCenter.Z + radius * Math.Cos(elevation * Math.PI / 180.0) * Math.Sin(azimuth * Math.PI / 180.0); - - // 更新相机位置和视角 + camera.Position = new Point3D(newX, newY, newZ); + camera.LookDirection = new Vector3D(modelCenter.X - newX, modelCenter.Y - newY, modelCenter.Z - newZ); - camera.UpDirection = new Vector3D(0, 1, 0); // 保持 Y 轴为上方向 + + var rightDirection = Vector3D.CrossProduct(camera.LookDirection, new Vector3D(0, 1, 0)); // 计算右方向 + + if (rightDirection.Length < 0.027) + { + rightDirection = Vector3D.CrossProduct(camera.LookDirection, new Vector3D(-1, 0, 0)); // 计算右方向 + } + + camera.UpDirection = Vector3D.CrossProduct(camera.LookDirection, rightDirection); + } + // private void BtnDirection_OnClick(object sender, RoutedEventArgs e) + // { + // var directionName = ((Button)sender).Name.ToString(); + // var directionValue = (int)TbCustomizeRevolve.Value; // 旋转角度(单位:度) + // + // if(directionValue == 0) return; + // // 获取当前相机和模型中心 + // var camera = Viewport3Dx.Camera as HelixToolkit.Wpf.SharpDX.PerspectiveCamera; + // if (camera == null) return; + // + // var modelCenter = ViewportManager.CenterVector; // 模型中心 + // var currentPosition = camera.Position; + // + // // 将相机位置转换为极坐标 + // var dx = currentPosition.X - modelCenter.X; + // var dy = currentPosition.Y - modelCenter.Y; + // var dz = currentPosition.Z - modelCenter.Z; + // + // var radius = Math.Sqrt(dx * dx + dy * dy + dz * dz); // 相机与模型中心的距离 + // var azimuth = Math.Atan2(dz, dx) * 180.0 / Math.PI; // 方位角(水平平面上的角度) + // var elevation = Math.Atan2(dy, Math.Sqrt(dx * dx + dz * dz)) * 180.0 / Math.PI; // 仰角(垂直方向的角度) + // + // switch (directionName) + // { + // case "BtnTop": + // //上 + // elevation += directionValue; + // break; + // case "BtnBottom": + // //下 + // elevation -= directionValue; + // break; + // case "BtnLeft": + // //左 + // azimuth -= directionValue; + // break; + // case "BtnRight": + // //右 + // azimuth += directionValue; + // break; + // } + // // 限制仰角范围在 -89.9 到 89.9 度,避免超出范围导致位置错误 + // // elevation = elevation > 90 || elevation < -90 ? ? elevation + 90 : elevation - 90: elevation; + // // elevation = elevation; + // int isFan = 1; + // if (elevation > 90 || elevation < -90) + // { + // if (elevation < -90) + // { + // elevation += 90; + // } + // else + // { + // elevation -= 90; + // isFan = -1; + // } + // } + // + // azimuth = (azimuth + 360) % 360; // 方位角在 0 到 360 范围内循环 + // + // // 将极坐标转换回直角坐标 + // var newX = modelCenter.X + radius * Math.Cos(elevation * Math.PI / 180.0) * Math.Cos(azimuth * Math.PI / 180.0); + // var newY = modelCenter.Y + radius * Math.Sin(elevation * Math.PI / 180.0); + // var newZ = modelCenter.Z + radius * Math.Cos(elevation * Math.PI / 180.0) * Math.Sin(azimuth * Math.PI / 180.0); + // + // // 更新相机位置和视角 + // camera.Position = new Point3D(newX, newY, newZ); + // camera.LookDirection = new Vector3D(modelCenter.X - newX, modelCenter.Y - newY, modelCenter.Z - newZ); + // camera.UpDirection = new Vector3D(camera.UpDirection.X, camera.UpDirection.Y * isFan, camera.UpDirection.Z); // 保持 Y 轴为上方向 + // + // + // + // } + #region 右键菜单事件绑定 /// @@ -495,5 +581,12 @@ public partial class Viewport3D #endregion - + private void TbCustomizeRevolve_OnMouseDoubleClick(object sender, MouseButtonEventArgs e) + { + Viewport3Dx.ShowCameraInfo = !Viewport3Dx.ShowCameraInfo; + Viewport3Dx.ShowCameraTarget = !Viewport3Dx.ShowCameraTarget ; + Viewport3Dx.ShowFrameDetails = !Viewport3Dx.ShowFrameDetails; + Viewport3Dx.ShowFrameRate = !Viewport3Dx.ShowFrameRate; + Viewport3Dx.ShowTriangleCountInfo = !Viewport3Dx.ShowTriangleCountInfo; + } } \ No newline at end of file diff --git a/Views/UserControl/ViewportData/Entity/ColorConfigEntity.cs b/Views/UserControl/ViewportData/Entity/ColorConfigEntity.cs index 9a559ac..aa519f5 100644 --- a/Views/UserControl/ViewportData/Entity/ColorConfigEntity.cs +++ b/Views/UserControl/ViewportData/Entity/ColorConfigEntity.cs @@ -11,7 +11,7 @@ public class ColorConfigEntity private string _mainFacetColor = "#FFBDD2ED"; private string _mainBorderColor = "#FF6959CC"; - private string _selFacetColor = "#FFBDB759"; + private string _selFacetColor = "#FFE8E187"; private string _selBorderColor = "#FF000000"; private string _selTypeColor = "#FFFCFCD1"; private string _selFontColor = "#FFFF0000"; diff --git a/Views/UserControl/ViewportData/Helper/ViewportHelperPro.cs b/Views/UserControl/ViewportData/Helper/ViewportHelperPro.cs index 7180a11..4a3824e 100644 --- a/Views/UserControl/ViewportData/Helper/ViewportHelperPro.cs +++ b/Views/UserControl/ViewportData/Helper/ViewportHelperPro.cs @@ -3,12 +3,14 @@ using System.Collections.ObjectModel; using System.Diagnostics; using System.Drawing.Text; using System.IO; +using System.Text.Json.Nodes; using System.Windows; using System.Windows.Media; using System.Windows.Media.Animation; using System.Windows.Media.Imaging; using System.Windows.Media.Media3D; using System.Windows.Threading; +using HandyControl.Controls; using HelixToolkit.Wpf.SharpDX; using log4net; using NPOI.OpenXmlFormats.Vml.Office; @@ -415,8 +417,8 @@ public class ViewportHelperPro else ViewportManager.GirdleTopLines.Add(vector); } - 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.GirdleBottomLines), color??ViewportManager.ColorConfig.MainBorderColor, thickness)); + // result.Add(DisplayLineModel3D( VectorClockwiseSort(ViewportManager.GirdleTopLines), color??ViewportManager.ColorConfig.MainBorderColor, thickness)); } @@ -474,24 +476,99 @@ public class ViewportHelperPro var groupedDic = facetTypeAll.GroupBy(entity => entity.PlaneCode) .ToDictionary(group => group.Key, group => group.ToList()); Logger.Info($"【面文本生成】 腰由{groupedDic.Count}个面组成"); - foreach (var kv in groupedDic) + + 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) { - var value = kv.Value; - var key = kv.Key; - var facetIndex = -1; - int.TryParse(key.Split("_")[1], out facetIndex); - List facetPoints = new List(); - value.ForEach(e => { facetPoints.Add(e.Point1); facetPoints.Add(e.Point2); facetPoints.Add(e.Point3); }); - /*** - * 0 1 2 3 - * 4 5 6 7 - * 面id-loop4 = 0 - 高亮左边的竖线 - 波峰 - - * 面id-loop4 = 1 - 高亮右边的竖线 - 波谷 - * 面id-loop4 = 2 - 高亮左边的竖线 - 波谷 - * 面id-loop4 = 3 - 高亮右边的竖线 - 波峰 - */ - + Logger.Info($"【面文本生成】 面索引解析失败{selPlaneCode}"); + return result; + } + int linePointType = facetIndex % 4; + + switch (linePointType) + { + case 0: + case 3: + var longestLine1 = GetLongestOrShortestLineSegment(facetPoints, returnLongest: true); + result.Add(DisplayLineModel3D(new List>(){longestLine1}, new Color4(1f, 0, 0, 1f) , 2f)); + break; + case 1: + case 2: + var longestLine2 = GetLongestOrShortestLineSegment(facetPoints, returnLongest: false); + result.Add(DisplayLineModel3D(new List>(){longestLine2}, new Color4(1f, 0, 0, 1f) , 2f)); + break; + } + //开始找值 + 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, textColor)); + // foreach (var kv in groupedDic) + // { + // var value = kv.Value; + // var key = kv.Key; + // var facetIndex = -1; + // int.TryParse(key.Split("_")[1], out facetIndex); + // List facetPoints = new List(); + // value.ForEach(e => { facetPoints.Add(e.Point1); facetPoints.Add(e.Point2); facetPoints.Add(e.Point3); }); + // + // int linePointType = facetIndex % 4; + // /*** + // * 0 1 2 3 + // * 4 5 6 7 + // * 面index+1 % 4 = 0 + // * 面id-loop4 = 0 - 高亮左边的竖线 - 波峰 - + // * 面id-loop4 = 1 - 高亮右边的竖线 - 波谷 + // * 面id-loop4 = 2 - 高亮左边的竖线 - 波谷 + // * 面id-loop4 = 3 - 高亮右边的竖线 - 波峰 + // */ + // + // } } else { @@ -515,7 +592,12 @@ public class ViewportHelperPro { Logger.Info($"【面文本生成】 钻石数据有效,Index有效"); facetIndex += 1; - var param = ViewportManager.DicFacetToValueParam[selFacetType]; + var param = ViewportManager.DicFacetToValueParam.ContainsKey(selFacetType) ? ViewportManager.DicFacetToValueParam[selFacetType] : null; + if (param == null) + { continue; + + } + var detail = ViewportManager.DiamondData[$"{param}_DETAIL"]; if (detail == null) { @@ -531,10 +613,10 @@ public class ViewportHelperPro } Logger.Info($"【面文本生成】 {param}_DETAIL.{param}_{facetIndex} ==={paramValue}"); - var valueFloat = Math.Round(float.Parse(paramValue.ToString()), MidpointRounding.ToZero); + var valueFloat = float.Parse(paramValue.ToString()).ToString("F1"); Logger.Info($"【面文本生成】 {valueFloat} -- {facetIndex}"); var facetTextPoint = GetOffsetCenter(facetPoints, ViewportManager.CenterVector); - result.Add(DisplayText3D($" {facetIndex} \r\n {valueFloat}", facetTextPoint, textColor)); + result.Add(DisplayText3D($" {facetIndex} \r\n {valueFloat}", facetTextPoint, textColor)); } } @@ -1213,6 +1295,41 @@ public class ViewportHelperPro } return false; // 不平行于 Y 轴 } + // 计算两个点之间的距离 + private static float GetDistance(Vector3 point1, Vector3 point2) + { + return (float)Math.Sqrt(Math.Pow(point2.X - point1.X, 2) + Math.Pow(point2.Y - point1.Y, 2) + Math.Pow(point2.Z - point1.Z, 2)); + } + +// 判断是否平行于Y轴的线段,返回较长或者较短的线段 + private static Tuple GetLongestOrShortestLineSegment(List facetPoints, bool returnLongest = true) + { + Tuple resultSegment = null; + float resultLength = returnLongest ? float.MinValue : float.MaxValue; // 初始化为最小或最大长度 + + // 遍历所有相邻的点,构成线段 + for (int i = 0; i < facetPoints.Count; i++) + { + Vector3 currentPoint = facetPoints[i]; + Vector3 nextPoint = facetPoints[(i + 1) % facetPoints.Count]; // 用模运算实现环形结构,最后一个点与第一个点连接 + + // 计算线段是否平行于 Y 轴 + if (IsLineSegmentParallelToYAxis(new Tuple(currentPoint, nextPoint))) + { + // 计算线段的长度 + float segmentLength = GetDistance(currentPoint, nextPoint); + + // 根据需要选择较长或较短的线段 + if ((returnLongest && segmentLength > resultLength) || (!returnLongest && segmentLength < resultLength)) + { + resultSegment = new Tuple(currentPoint, nextPoint); + resultLength = segmentLength; + } + } + } + + return resultSegment; // 返回符合条件的线段 + } private static void CalculateLineSegmentStats(List> lines, out Tuple maxLine, out Tuple minLine, diff --git a/Views/UserControl/ViewportData/Helper/ViewportManager.cs b/Views/UserControl/ViewportData/Helper/ViewportManager.cs index cb47df4..c0789dd 100644 --- a/Views/UserControl/ViewportData/Helper/ViewportManager.cs +++ b/Views/UserControl/ViewportData/Helper/ViewportManager.cs @@ -95,7 +95,7 @@ public class ViewportManager //选中边框夹角文字 public static bool DoubleClickSelectShowBorderAngle = false; - public static bool DoubleClickSelectShowInfoText = false; + public static bool DoubleClickSelectShowInfoText = true; //选中同类面 public static bool DoubleClickSelectShowPlaneType = true; //选中三角形代码 @@ -140,13 +140,13 @@ public class ViewportManager public static Dictionary DicFacetToValueParam = new Dictionary() { { PlaneType.UpperMainFacet,"CROWN_ANGLE"}, - { PlaneType.LowerGirdleFact, "PAV_ANGLE"}, + { PlaneType.PavilionMainFacet, "PAV_ANGLE"}, }; // 数据 -> 面 public static Dictionary DicValueParamToFacet = new Dictionary() { {"CROWN_ANGLE", PlaneType.UpperMainFacet}, - {"PAV_ANGLE", PlaneType.LowerGirdleFact}, + {"PAV_ANGLE", PlaneType.PavilionMainFacet}, }; #endregion #endregion