diff --git a/Language/en_US.xaml b/Language/en_US.xaml index ea90373..469153c 100644 --- a/Language/en_US.xaml +++ b/Language/en_US.xaml @@ -71,6 +71,11 @@ Button + + + Item Name + Operation + Del Button diff --git a/Language/zh_CN.xaml b/Language/zh_CN.xaml index 67c1936..fc8f0a6 100644 --- a/Language/zh_CN.xaml +++ b/Language/zh_CN.xaml @@ -72,6 +72,11 @@ 按钮 + + 项目名称 + 操作 + 删除 + 按钮 diff --git a/Model/Entity/JsonEntity.cs b/Model/Entity/JsonEntity.cs index a494e04..fd7dd29 100644 --- a/Model/Entity/JsonEntity.cs +++ b/Model/Entity/JsonEntity.cs @@ -1,4 +1,5 @@ -using System; +using SparkClient.ViewModel.Grading; +using System; using System.Collections.Generic; using System.Data; using System.Linq; @@ -80,7 +81,7 @@ namespace EncryptFileTool.Entity public string TEST_ITEM_ID { get; set; } public string STANDARD_ID { get; set; } public string STANDARD_NAME { get; set; } - public string STANDARD_EN_NAME { get; set; } + public string STANDARD_EN_NAME { get{ return getStandEnName(); } set { } } public string STANDARD_MIN { get; set; } public string STANDARD_MAX { get; set; } public string IS_MIN_EXIST { get; set; } = "0"; @@ -93,6 +94,11 @@ namespace EncryptFileTool.Entity public string MIN_NULL_REPALCE { get; set; } = "←"; public string MAX_NULL_REPALCE { get; set; } = "→"; public int SORT { get; set; } + private string getStandEnName() + { + return Name.getNameById(TEST_ITEM_ID).Trim(); + + } } public class GradeConfigInfo { diff --git a/Resource/Document/Helper.pdf b/Resource/Document/Helper.pdf index 271a04a..cc28659 100644 Binary files a/Resource/Document/Helper.pdf and b/Resource/Document/Helper.pdf differ diff --git a/Resource/Document/Helper_en.pdf b/Resource/Document/Helper_en.pdf new file mode 100644 index 0000000..113521d Binary files /dev/null and b/Resource/Document/Helper_en.pdf differ diff --git a/SparkClient.csproj b/SparkClient.csproj index dfac916..f58872c 100644 --- a/SparkClient.csproj +++ b/SparkClient.csproj @@ -29,6 +29,7 @@ + @@ -98,6 +99,9 @@ Always + + Always + diff --git a/SparkClient.sln.DotSettings.user b/SparkClient.sln.DotSettings.user index 79d18e2..117353a 100644 --- a/SparkClient.sln.DotSettings.user +++ b/SparkClient.sln.DotSettings.user @@ -15,6 +15,7 @@ ForceIncluded ForceIncluded ForceIncluded + ForceIncluded ForceIncluded ForceIncluded ForceIncluded @@ -28,6 +29,7 @@ ForceIncluded ForceIncluded ForceIncluded + ForceIncluded ForceIncluded ForceIncluded ForceIncluded @@ -68,6 +70,7 @@ ForceIncluded ForceIncluded ForceIncluded + ForceIncluded ForceIncluded ForceIncluded ForceIncluded @@ -77,6 +80,7 @@ ForceIncluded ForceIncluded ForceIncluded + ForceIncluded ForceIncluded ForceIncluded ForceIncluded diff --git a/SparkDB.db b/SparkDB.db index dc64fef..b73a0d3 100644 Binary files a/SparkDB.db and b/SparkDB.db differ diff --git a/ViewModel/Configuration/CutConfigVM.cs b/ViewModel/Configuration/CutConfigVM.cs index b61c7d0..d1c82c6 100644 --- a/ViewModel/Configuration/CutConfigVM.cs +++ b/ViewModel/Configuration/CutConfigVM.cs @@ -167,11 +167,11 @@ public class CutConfigVM: BaseViewModel } if (insertCount>=0) { - Growl.Info("保存成功"); + Growl.Info(MultilingualHelper.getString("ViewportSaveSucceed")); } else { - Growl.Error("保存失败"); + Growl.Error(MultilingualHelper.getString("ViewportSaveFail")); } } catch (Exception ex) diff --git a/ViewModel/Configuration/LevelConfigVM.cs b/ViewModel/Configuration/LevelConfigVM.cs index 9a7c9c6..9f6cb3a 100644 --- a/ViewModel/Configuration/LevelConfigVM.cs +++ b/ViewModel/Configuration/LevelConfigVM.cs @@ -368,19 +368,20 @@ public class LevelConfigVM : BaseViewModel string ta = ruleId.Substring(ruleId.Length - 2); // 国标场合 按照规则id中涵盖信息不同 对测试项目有不同描述 + string itemName = Name.getNameById("TABLE").Trim(); if (ruleId.StartsWith("GB")) { if ("49".Equals(ta)) { - prefix = "[台宽比<" + ruleId.Substring(ruleId.Length - 2) + "] "; + prefix = $"[{itemName}<" + ruleId.Substring(ruleId.Length - 2) + "] "; } else if ("71".Equals(ta)) { - prefix = "[台宽比>" + ruleId.Substring(ruleId.Length - 2) + "] "; + prefix = $"[{itemName}>" + ruleId.Substring(ruleId.Length - 2) + "] "; } else { - prefix = "[台宽比=" + ruleId.Substring(ruleId.Length - 2) + "] "; + prefix = $"[{itemName}=" + ruleId.Substring(ruleId.Length - 2) + "] "; } } } diff --git a/Views/Configuration/CutConfigPage.xaml b/Views/Configuration/CutConfigPage.xaml index b7f7407..a4ef03e 100644 --- a/Views/Configuration/CutConfigPage.xaml +++ b/Views/Configuration/CutConfigPage.xaml @@ -101,7 +101,7 @@ - + - + - diff --git a/Views/HelperPage.xaml.cs b/Views/HelperPage.xaml.cs index 2473f17..09e3dce 100644 --- a/Views/HelperPage.xaml.cs +++ b/Views/HelperPage.xaml.cs @@ -1,21 +1,62 @@ using System.Windows; using System.Windows.Controls; +using log4net; using Microsoft.Web.WebView2.Core; +using SparkClient.Model.Helper; +using SparkClient.ViewModel.Configuration; namespace SparkClient.Views; public partial class HelperPage { + private static readonly ILog Logger = LogManager.GetLogger(typeof(HelperPage)); public HelperPage() { InitializeComponent(); - - PdfWebViewer.Source = new Uri(AppDomain.CurrentDomain.BaseDirectory + @"Resource\Document\Helper.pdf"); - + InitializeWebView(); + } + + private async void InitializeWebView() + { + try + { + string language = ""; + if ("zh-cn".Equals(MultilingualHelper.getLangType())) + { + language = "zh-CN"; + } + else + { + language = "en-US"; + } + string userDataFolder = AppDomain.CurrentDomain.BaseDirectory + @"UserData\pdf_"+language; + // 设置语言 + var environment = await CoreWebView2Environment.CreateAsync( + browserExecutableFolder: null, // 使用默认的WebView2运行时 + userDataFolder: userDataFolder, // 使用默认的用户数据文件夹 + options: new CoreWebView2EnvironmentOptions + { + Language = language // 设置语言 + }); + + // 初始化WebView2控件 + await PdfWebViewer.EnsureCoreWebView2Async(environment); - + if ("zh-CN".Equals(language)) + { + PdfWebViewer.Source = new Uri(AppDomain.CurrentDomain.BaseDirectory + @"Resource\Document\Helper.pdf"); + } + else + { + PdfWebViewer.Source = new Uri(AppDomain.CurrentDomain.BaseDirectory + @"Resource\Document\Helper_en.pdf"); + } + + } + catch (Exception ex) + { + Logger.Error($"全局异常捕获:{ex.Message}", ex); + } } - } \ No newline at end of file diff --git a/Views/UserControl/Viewport3D.xaml.cs b/Views/UserControl/Viewport3D.xaml.cs index afdbbc8..e1effc6 100644 --- a/Views/UserControl/Viewport3D.xaml.cs +++ b/Views/UserControl/Viewport3D.xaml.cs @@ -17,6 +17,7 @@ using SharpDX.Direct3D11; using SharpDX.DXGI; using MathNet.Numerics; using System.Windows.Media; +using ObjExporter = SparkClient.Views.UserControl.ViewportData.Helper.ObjExporter; namespace SparkClient.Views.UserControl; @@ -46,7 +47,7 @@ public partial class Viewport3D ViewportManager.LoadModelByEntities(new List()); #if DEBUG #else - BtnShow3DView.Visibility = Visibility.Hidden; + // BtnShow3DView.Visibility = Visibility.Hidden; #endif //选项初始化 显示-后端-管理类 一致 @@ -218,7 +219,8 @@ public partial class Viewport3D ViewportManager.DoubleClickSelect = !false; break; case "BtnShow3DView": - UnityHelper.GenerateRender(ViewportManager.ViewportTriangle.First().TriangleCode, "123"); + ObjExporter.ExportToObj2(ViewportManager.ViewportTriangle, @"D:\id03.obj"); + //UnityHelper.GenerateRender(ViewportManager.ViewportTriangle.First().TriangleCode, "123"); break; } diff --git a/Views/UserControl/ViewportData/Helper/ObjExporter.cs b/Views/UserControl/ViewportData/Helper/ObjExporter.cs new file mode 100644 index 0000000..3064d1d --- /dev/null +++ b/Views/UserControl/ViewportData/Helper/ObjExporter.cs @@ -0,0 +1,161 @@ +using System.IO; +using System.Text; +using SharpDX; +using SparkClient.Views.UserControl.ViewportData.Entity; +using SparkClient.Views.UserControl.ViewportData.Enum; + +namespace SparkClient.Views.UserControl.ViewportData.Helper; + +public class ObjExporter +{ + + public static void ExportToObj2(List entities, string outputPath) + { + //分组 + Dictionary> feactList = entities + .Where(entity => entity.PlaneType != PlaneType.Girdle) + .GroupBy(entity => entity.PlaneCode) + .ToDictionary(group => group.Key, group => group.ToList()); + //腰 单组 + // List waistList = entities + // .Where(entity => entity.PlaneType == PlaneType.Girdle) + // .ToList(); + Dictionary> gridleList = entities + .Where(entity => entity.PlaneType == PlaneType.Girdle) + .GroupBy(entity => entity.PlaneCode) + .ToDictionary(group => group.Key, group => group.ToList()); + + //同一个面只保留外边框(除了腰) + Dictionary> resultPoints = new Dictionary>(); + + foreach (var dic in feactList) + { + List tempPoints = new List(); + foreach (var entity in dic.Value) + { + tempPoints.Add(entity.Point1); + tempPoints.Add(entity.Point2); + tempPoints.Add(entity.Point3); + } + resultPoints.Add(dic.Key, ViewportHelperPro.VectorClockwiseSort(new HashSet(tempPoints).ToList())); + } + + foreach (var dic in gridleList) + { + List tempPoints = new List(); + foreach (var entity in dic.Value) + { + tempPoints.Add(entity.Point1); + tempPoints.Add(entity.Point2); + tempPoints.Add(entity.Point3); + } + resultPoints.Add(dic.Key, ViewportHelperPro.VectorClockwiseSort(new HashSet(tempPoints).ToList())); + } + // List selFaceVector = new List(); + // if (waistList.Count > 0) + // { + // foreach (var entity in waistList) + // { + // selFaceVector.Add(entity.Point1); + // selFaceVector.Add(entity.Point2); + // selFaceVector.Add(entity.Point3); + // } + // } + // resultPoints.Add("yao", selFaceVector); + + StringBuilder sb = new StringBuilder(); + + // 顶点列表 + List uniqueVertices = new List(); + Dictionary vertexIndexMap = new Dictionary(); + + // 1. 对每个面生成顶点和面 + foreach (var face in resultPoints) + { + // 对每个面,获取它的顶点列表 + List faceVertices = face.Value; + + // 去重顶点 + foreach (var vertex in faceVertices) + { + if (!vertexIndexMap.ContainsKey(vertex)) + { + vertexIndexMap[vertex] = uniqueVertices.Count; + uniqueVertices.Add(vertex); + } + } + } + + // 2. 写入顶点数据 + foreach (var vertex in uniqueVertices) + { + sb.AppendLine($"v {vertex.X} {vertex.Y} {vertex.Z}"); + } + + // 3. 写入每个面(f行),包括正面和反面 + foreach (var face in resultPoints) + { + sb.AppendLine($"# Face: {face.Key}"); + + // 获取面上的所有顶点并排序 + List faceVertices = face.Value; + if (!face.Key.StartsWith("11_")) + { + Vector3 center = GetCenterOfVertices(faceVertices); + faceVertices.Sort((v1, v2) => GetAngle(v1, center).CompareTo(GetAngle(v2, center))); + } + + + + // 正面:按顺时针顺序输出 + sb.Append("f"); + foreach (var vertex in faceVertices) + { + sb.Append($" {vertexIndexMap[vertex] + 1}"); + } + sb.AppendLine(); + + // 反面:按逆时针顺序输出(反转顶点顺序) + sb.Append("f"); + for (int i = faceVertices.Count - 1; i >= 0; i--) + { + sb.Append($" {vertexIndexMap[faceVertices[i]] + 1}"); + } + sb.AppendLine(); + } + + // 4. 写入文件 + File.WriteAllText(outputPath, sb.ToString()); + + } + + // 计算一组顶点的中心点(用于排序) + private static Vector3 GetCenterOfVertices(List vertices) + { + float centerX = 0, centerY = 0, centerZ = 0; + foreach (var vertex in vertices) + { + centerX += vertex.X; + centerY += vertex.Y; + centerZ += vertex.Z; + } + return new Vector3(centerX / vertices.Count, centerY / vertices.Count, centerZ / vertices.Count); + } + + private static float GetAngle(Vector3 vertex, Vector3 center) + { + // 计算顶点与中心的方向向量 + Vector3 direction = vertex - center; + + // 在XY平面上计算角度 + float angle = (float)Math.Atan2(direction.Y, direction.X); // 返回的是弧度,[-π, π] + + // 如果你想要角度范围 [0, 2π],可以做如下处理 + if (angle < 0) + { + angle += MathF.PI * 2; + } + + return angle; + } +} \ No newline at end of file